First check-in of Orbot: the Onion Routing Robot (aka Tor on Android)

svn:r20811
This commit is contained in:
Nathan Freitas 2009-10-21 23:17:45 +00:00
commit 3d0dc69f9f
28 changed files with 2475 additions and 0 deletions

8
.classpath Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="lib" path="commons-lang-2.4.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

39
.project Normal file
View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Orbot</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>

11
.settings/.jsdtscope Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>

View File

@ -0,0 +1 @@
org.eclipse.wst.jsdt.launching.baseBrowserLibrary

View File

@ -0,0 +1 @@
Window

27
AUTHORS Normal file
View File

@ -0,0 +1,27 @@
This file lists the authors for Orbot,
a free software project to provide anonymity on the Internet on Android smartphones.
For more information about Orbot, see http://openideals.com/guardian
If you got this file as a part of a larger bundle,
there are probably other authors that you should be aware of.
Main Authors:
-------------
Nathan Freitas <nathan@freitas.net> developed the primary
Android application and managed the porting of Tor to Android.
Contributors:
-------------
Jack Appelbaum <jake@appelbaum.net > regular gave Nathan a
swift kick in the rear to get this done. He has also provided
extensive guidance and review.
Nick Mathewson <nickm@freehaven.net> wrote some of the patch
code to support the compiling of Tor and LibEvent on Android,
and generaly provided guidance in the entire effort.
Adam Langley <> made the original valiant effort to port
Tor to Android.

23
AndroidManifest.xml Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.torproject.android"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<application android:icon="@drawable/icon" android:label="@string/app_name"
android:debuggable="true">
<activity android:name=".TorControlPanel"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".TorService" android:enabled="true" android:exported="true"/>
</application>
</manifest>

316
LICENSE Normal file
View File

@ -0,0 +1,316 @@
This file contains the license for Orbot, a free software project to provide anonymity on the Internet from a Google Android smartphone.
It also lists the licenses for other components used by Orbot.
For more information about Orbot, see http://openideals.com/guardian
If you got this file as a part of a larger bundle, there may be other license terms that you should be aware of.
===============================================================================
Orbot is distributed under this license (aka The Tor License)
Copyright (c) 2009-2011, Nathan Freitas, The Guardian Project
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the names of the copyright owners nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****
Orbot contains a binary distribution of the JSocks library: http://code.google.com/p/jsocks-mirror/
which is licensed under the GNU Lesser General Public License: http://www.gnu.org/licenses/lgpl.html
*****
Orbot contains the source code for HttpProxy developed and freely licensed by: Julian Robichaux -- http://www.nsftools.com
******
Orbot contains a binary distribution of Tor:
This file contains the license for Tor,
a free software project to provide anonymity on the Internet.
It also lists the licenses for other components used by Tor.
For more information about Tor, see https://www.torproject.org/.
If you got this file as a part of a larger bundle,
there may be other license terms that you should be aware of.
===============================================================================
Tor is distributed under this license:
Copyright (c) 2001-2004, Roger Dingledine
Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
Copyright (c) 2007-2009, The Tor Project, Inc.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the names of the copyright owners nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===============================================================================
src/common/strlcat.c and src/common/strlcpy.c by Todd C. Miller are licensed
under the following license:
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
:src/common/strlcat.c and src/common/strlcpy.c by Todd C. Miller are licensed
under the following license:
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
:src/common/strlcat.c and src/common/strlcpy.c by Todd C. Miller are licensed
under the following license:
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCD FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
:src/common/strlcat.c and src/common/strlcpy.c by Todd C. Miller are licensed
under the following license:
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
:src/common/strlcat.c and src/common/strlcpy.c by Todd C. Miller are licensed
under the following license:
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===============================================================================
If you got Tor as a static binary with OpenSSL included, then you should know:
"This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit (http://www.openssl.org/)"
===============================================================================
"This program uses the IP-to-Country Database provided by
WebHosting.Info (http://www.webhosting.info), available from
http://ip-to-country.webhosting.info."
See the src/config/geoip file in particular.
:src/common/strlcat.c and src/common/strlcpy.c by Todd C. Miller are licensed
under the following license:
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===============================================================================
If you got Tor as a static binary with OpenSSL included, then you should know:
"This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit (http://www.openssl.org/)"
===============================================================================
"This program uses the IP-to-Country Database provided by
WebHosting.Info (http://www.webhosting.info), available from
http://ip-to-country.webhosting.info."
See the src/config/geoip file in particular.
:src/common/strlcat.c and src/common/strlcpy.c by Todd C. Miller are licensed
under the following license:
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===============================================================================
If you got Tor as a static binary with OpenSSL included, then you should know:
"This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit (http://www.openssl.org/)"
===============================================================================
"This program uses the IP-to-Country Database provided by
WebHosting.Info (http://www.webhosting.info), available from
http://ip-to-country.webhosting.info."
See the src/config/geoip file in particular.
===============================================================================

25
README Normal file
View File

@ -0,0 +1,25 @@
Orbot: Android Onion Routing Robot
***********************************************
This is a freely licensed open-source application developed for the
Android platform, that acts as a front-end to the Tor binary application.
Orbot also provides an HTTP Proxy for connecting web browsers and other
HTTP client applications into the Tor SOCKS interface.
***********************************************
Orbot is a component of the Guardian Project, an effort to develope
a secure, anonymous smartphone for use by human rights activists, journalists
and others around the world. Learn more: http://openideals.com/guardian
***********************************************
Tor protects your privacy on the internet by hiding the connection
between your Internet address and the services you use. We believe Tor
is reasonably secure, but please ensure you read the instructions and
configure it properly. Learn more at http://torproject.org
Tor Frequently Asked Questions:
https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ
***********************************************
/* Copyright (c) 2009-2011, Nathan Freitas, The Guardian Project - http://openideals.com/guardian */

BIN
assets/tor Executable file

Binary file not shown.

169
assets/torrc Normal file
View File

@ -0,0 +1,169 @@
## Configuration file for a typical Tor user
## Last updated 16 July 2009 for Tor 0.2.2.1-alpha.
## (May or may not work for much older or much newer versions of Tor.)
##
## Lines that begin with "## " try to explain what's going on. Lines
## that begin with just "#" are disabled commands: you can enable them
## by removing the "#" symbol.
##
## See 'man tor', or https://www.torproject.org/tor-manual.html,
## for more options you can use in this file.
##
## Tor will look for this file in various places based on your platform:
## https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#torrc
## Replace this with "SocksPort 0" if you plan to run Tor only as a
## relay, and not make any local application connections yourself.
SocksPort 9050 # what port to open for local application connections
SocksListenAddress 127.0.0.1 # accept connections only from localhost
#SocksListenAddress 192.168.0.1:9100 # listen on this IP:port also
## Entry policies to allow/deny SOCKS requests based on IP address.
## First entry that matches wins. If no SocksPolicy is set, we accept
## all (and only) requests from SocksListenAddress.
#SocksPolicy accept 192.168.0.0/16
#SocksPolicy reject *
## Logs go to stdout at level "notice" unless redirected by something
## else, like one of the below lines. You can have as many Log lines as
## you want.
##
## We advise using "notice" in most cases, since anything more verbose
## may provide sensitive information to an attacker who obtains the logs.
##
## Send all messages of level 'notice' or higher to @LOCALSTATEDIR@/log/tor/notices.log
Log notice file /data/data/org.torproject.android/notices.log
## Send every possible message to @LOCALSTATEDIR@/log/tor/debug.log
#Log debug file /data/data/org.torproject.android/debug.log
## Use the system log instead of Tor's logfiles
#Log notice syslog
## To send all messages to stderr:
#Log debug stderr
## Uncomment this to start the process in the background... or use
## --runasdaemon 1 on the command line. This is ignored on Windows;
## see the FAQ entry if you want Tor to run as an NT service.
#RunAsDaemon 1
## The directory for keeping all the keys/etc. By default, we store
## things in $HOME/.tor on Unix, and in Application Data\tor on Windows.
DataDirectory /data/data/org.torproject.android/data
## The port on which Tor will listen for local connections from Tor
## controller applications, as documented in control-spec.txt.
#ControlPort 9051
## If you enable the controlport, be sure to enable one of these
## authentication methods, to prevent attackers from accessing it.
#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C
#CookieAuthentication 1
############### This section is just for location-hidden services ###
## Once you have configured a hidden service, you can look at the
## contents of the file ".../hidden_service/hostname" for the address
## to tell people.
##
## HiddenServicePort x y:z says to redirect requests on port x to the
## address y:z.
#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/hidden_service/
#HiddenServicePort 80 127.0.0.1:80
#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/other_hidden_service/
#HiddenServicePort 80 127.0.0.1:80
#HiddenServicePort 22 127.0.0.1:22
################ This section is just for relays #####################
#
## See https://www.torproject.org/docs/tor-doc-relay for details.
## Required: what port to advertise for incoming Tor connections.
#ORPort 9001
## If you want to listen on a port other than the one advertised
## in ORPort (e.g. to advertise 443 but bind to 9090), uncomment the
## line below too. You'll need to do ipchains or other port forwarding
## yourself to make this work.
#ORListenAddress 0.0.0.0:9090
## A handle for your relay, so people don't have to refer to it by key.
#Nickname ididnteditheconfig
## The IP address or full DNS name for your relay. Leave commented out
## and Tor will guess.
#Address noname.example.com
## Define these to limit how much relayed traffic you will allow. Your
## own traffic is still unthrottled. Note that RelayBandwidthRate must
## be at least 20 KBytes.
#RelayBandwidthRate 100 KBytes # Throttle traffic to 100KB/s (800Kbps)
#RelayBandwidthBurst 200 KBytes # But allow bursts up to 200KB/s (1600Kbps)
## Use these to restrict the maximum traffic per day, week, or month.
## Note that this threshold applies to sent _and_ to received bytes,
## not to their sum: Setting "4 GBytes" may allow up to 8 GBytes
## total before hibernating.
##
## Set a maximum of 4 gigabytes each way per period.
#AccountingMax 4 GBytes
## Each period starts daily at midnight (AccountingMax is per day)
#AccountingStart day 00:00
## Each period starts on the 3rd of the month at 15:00 (AccountingMax
## is per month)
#AccountingStart month 3 15:00
## Contact info to be published in the directory, so we can contact you
## if your relay is misconfigured or something else goes wrong. Google
## indexes this, so spammers might also collect it.
#ContactInfo Random Person <nobody AT example dot com>
## You might also include your PGP or GPG fingerprint if you have one:
#ContactInfo 1234D/FFFFFFFF Random Person <nobody AT example dot com>
## Uncomment this to mirror directory information for others. Please do
## if you have enough bandwidth.
#DirPort 9030 # what port to advertise for directory connections
## If you want to listen on a port other than the one advertised
## in DirPort (e.g. to advertise 80 but bind to 9091), uncomment the line
## below too. You'll need to do ipchains or other port forwarding yourself
## to make this work.
#DirListenAddress 0.0.0.0:9091
## Uncomment to return an arbitrary blob of html on your DirPort. Now you
## can explain what Tor is if anybody wonders why your IP address is
## contacting them. See contrib/tor-exit-notice.html for a sample.
#DirPortFrontPage /etc/tor/exit-notice.html
## Uncomment this if you run more than one Tor relay, and add the identity
## key fingerprint of each Tor relay you control, even if they're on
## different networks. You declare it here so Tor clients can avoid
## using more than one of your relays in a single circuit. See
## https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#MultipleServers
#MyFamily $keyid,$keyid,...
## A comma-separated list of exit policies. They're considered first
## to last, and the first match wins. If you want to _replace_
## the default exit policy, end this with either a reject *:* or an
## accept *:*. Otherwise, you're _augmenting_ (prepending to) the
## default exit policy. Leave commented to just use the default, which is
## described in the man page or at
## https://www.torproject.org/documentation.html
##
## Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses
## for issues you might encounter if you use the default exit policy.
##
## If certain IPs and ports are blocked externally, e.g. by your firewall,
## you should update your exit policy to reflect this -- otherwise Tor
## users will be told that those destinations are down.
##
#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more
#ExitPolicy accept *:119 # accept nntp as well as default exit policy
#ExitPolicy reject *:* # no exits allowed
#
## Bridge relays (or "bridges") are Tor relays that aren't listed in the
## main directory. Since there is no complete public list of them, even if an
## ISP is filtering connections to all the known Tor relays, they probably
## won't be able to block all the bridges. Also, websites won't treat you
## differently because they won't know you're running Tor. If you can
## be a real relay, please do; but if not, be a bridge!
#BridgeRelay 1
#ExitPolicy reject *:*

3
bcdroid.manifest Normal file
View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Sealed: true

22
default.properties Normal file
View File

@ -0,0 +1,22 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# apk configurations. This property allows creation of APK files with limited
# resources. For example, if your application contains many locales and
# you wish to release multiple smaller apks instead of a large one, you can
# define configuration to create apks with limited language sets.
# Format is a comma separated list of configuration names. For each
# configuration, a property will declare the resource configurations to
# include. Example:
# apk-configurations=european,northamerica
# apk-config-european=en,fr,it,de,es
# apk-config-northamerica=en,es
apk-configurations=
# Project target.
target=android-3

BIN
jsocks.jar Normal file

Binary file not shown.

BIN
res/drawable/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
res/drawable/tor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
res/drawable/toroff.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
res/drawable/toron.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

28
res/layout/layout_log.xml Normal file
View File

@ -0,0 +1,28 @@
<?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">
<ScrollView android:layout_height="380px"
android:layout_width="fill_parent" android:id="@+id/logScrollView">
<TextView android:id="@+id/messageLog"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_weight="1.0"
/>
</ScrollView>
<Button android:id="@+id/btnLogClose"
android:layout_width="fill_parent"
android:layout_height="40px"
android:text="Close Log"
android:layout_margin="0sp"
/>
</LinearLayout>

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
android:id="@+id/widget29"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#cccccc"
>
<AbsoluteLayout
android:id="@+id/topbox"
android:layout_width="275px"
android:layout_height="120px"
android:layout_x="19px"
android:layout_y="23px"
>
<ImageView
android:id="@+id/imgStatus"
android:layout_x="40px"
android:layout_y="11px"
android:layout_width="64px"
android:layout_height="64px"
>
</ImageView>
<TextView
android:id="@+id/lblStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:layout_x="111px"
android:layout_y="39px"
android:textColor="#333333"
>
</TextView>
</AbsoluteLayout>
<Button
android:id="@+id/btnStart"
android:layout_width="205px"
android:layout_height="wrap_content"
android:text="Start Tor"
android:layout_x="54px"
android:layout_y="133px"
>
</Button>
<Button
android:id="@+id/btnLog"
android:layout_width="206px"
android:layout_height="wrap_content"
android:text="View Message Log"
android:layout_x="54px"
android:layout_y="221px"
>
</Button>
<Button
android:id="@+id/btnSettings"
android:layout_width="206px"
android:layout_height="wrap_content"
android:text="View Settings"
android:layout_x="53px"
android:layout_y="305px"
>
</Button>
</AbsoluteLayout>

View File

@ -0,0 +1,28 @@
<?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">
<ScrollView android:layout_height="380px"
android:layout_width="fill_parent">
<TextView android:id="@+id/textSettings"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_weight="1.0"
/>
</ScrollView>
<Button android:id="@+id/btnSettingsClose"
android:layout_width="fill_parent"
android:layout_height="40px"
android:text="Close Log"
android:layout_margin="0sp"
/>
</LinearLayout>

6
res/values/strings.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Orbot</string>
<string name="app_version">0.0.1</string>
</resources>

View File

@ -0,0 +1,631 @@
package org.torproject.android;
/* <!-- in case someone opens this in a browser... --> <pre> */
/*
* This is a simple multi-threaded Java proxy server
* for HTTP requests (HTTPS doesn't seem to work, because
* the CONNECT requests aren't always handled properly).
* I implemented the class as a thread so you can call it
* from other programs and kill it, if necessary (by using
* the closeSocket() method).
*
* We'll call this the 1.1 version of this class. All I
* changed was to separate the HTTP header elements with
* \r\n instead of just \n, to comply with the official
* HTTP specification.
*
* This can be used either as a direct proxy to other
* servers, or as a forwarding proxy to another proxy
* server. This makes it useful if you want to monitor
* traffic going to and from a proxy server (for example,
* you can run this on your local machine and set the
* fwdServer and fwdPort to a real proxy server, and then
* tell your browser to use "localhost" as the proxy, and
* you can watch the browser traffic going in and out).
*
* One limitation of this implementation is that it doesn't
* close the ProxyThread socket if the client disconnects
* or the server never responds, so you could end up with
* a bunch of loose threads running amuck and waiting for
* connections. As a band-aid, you can set the server socket
* to timeout after a certain amount of time (use the
* setTimeout() method in the ProxyThread class), although
* this can cause false timeouts if a remote server is simply
* slow to respond.
*
* Another thing is that it doesn't limit the number of
* socket threads it will create, so if you use this on a
* really busy machine that processed a bunch of requests,
* you may have problems. You should use thread pools if
* you're going to try something like this in a "real"
* application.
*
* Note that if you're using the "main" method to run this
* by itself and you don't need the debug output, it will
* run a bit faster if you pipe the std output to 'nul'.
*
* You may use this code as you wish, just don't pretend
* that you wrote it yourself, and don't hold me liable for
* anything that it does or doesn't do. If you're feeling
* especially honest, please include a link to nsftools.com
* along with the code. Thanks, and good luck.
*
* Julian Robichaux -- http://www.nsftools.com
*/
import java.io.*;
import java.net.*;
import java.lang.reflect.Array;
import net.sourceforge.jsocks.socks.Socks4Proxy;
import net.sourceforge.jsocks.socks.Socks5Proxy;
import net.sourceforge.jsocks.socks.SocksSocket;
public class HttpProxy extends Thread
{
public static final int DEFAULT_PORT = 8888;
private ServerSocket server = null;
private int thisPort = DEFAULT_PORT;
private String fwdServer = "";
private int fwdPort = 0;
private int ptTimeout = ProxyThread.DEFAULT_TIMEOUT;
private int debugLevel = 0;
private PrintStream debugOut = System.out;
private boolean doSocks = false;
private Socks5Proxy sProxy = null;
/**
* @return the doSocks
*/
public boolean isDoSocks() {
return doSocks;
}
/**
* @param doSocks the doSocks to set
*/
public void setDoSocks(boolean doSocks) {
this.doSocks = doSocks;
}
/* here's a main method, in case you want to run this by itself */
public static void main (String args[])
{
int port = 0;
String fwdProxyServer = "";
int fwdProxyPort = 0;
if (args.length == 0)
{
System.err.println("USAGE: java jProxy <port number> [<fwd proxy> <fwd port>]");
System.err.println(" <port number> the port this service listens on");
System.err.println(" <fwd proxy> optional proxy server to forward requests to");
System.err.println(" <fwd port> the port that the optional proxy server is on");
System.err.println("\nHINT: if you don't want to see all the debug information flying by,");
System.err.println("you can pipe the output to a file or to 'nul' using \">\". For example:");
System.err.println(" to send output to the file prox.txt: java jProxy 8080 > prox.txt");
System.err.println(" to make the output go away: java jProxy 8080 > nul");
return;
}
// get the command-line parameters
port = Integer.parseInt(args[0]);
if (args.length > 2)
{
fwdProxyServer = args[1];
fwdProxyPort = Integer.parseInt(args[2]);
}
// create and start the jProxy thread, using a 20 second timeout
// value to keep the threads from piling up too much
System.err.println(" ** Starting jProxy on port " + port + ". Press CTRL-C to end. **\n");
HttpProxy jp = new HttpProxy(port, fwdProxyServer, fwdProxyPort, 20);
jp.setDebug(1, System.out); // or set the debug level to 2 for tons of output
jp.start();
// run forever; if you were calling this class from another
// program and you wanted to stop the jProxy thread at some
// point, you could write a loop that waits for a certain
// condition and then calls jProxy.closeSocket() to kill
// the running jProxy thread
while (true)
{
try { Thread.sleep(3000); } catch (Exception e) {}
}
// if we ever had a condition that stopped the loop above,
// we'd want to do this to kill the running thread
//jp.closeSocket();
//return;
}
/* the proxy server just listens for connections and creates
* a new thread for each connection attempt (the ProxyThread
* class really does all the work)
*/
public HttpProxy (int port)
{
thisPort = port;
try {
sProxy = new Socks5Proxy(TorConstants.IP_LOCALHOST,TorConstants.PORT_SOCKS);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sProxy.resolveAddrLocally(false);
}
public HttpProxy (int port, String proxyServer, int proxyPort)
{
thisPort = port;
fwdServer = proxyServer;
fwdPort = proxyPort;
}
public HttpProxy (int port, String proxyServer, int proxyPort, int timeout)
{
thisPort = port;
fwdServer = proxyServer;
fwdPort = proxyPort;
ptTimeout = timeout;
}
/* allow the user to decide whether or not to send debug
* output to the console or some other PrintStream
*/
public void setDebug (int level, PrintStream out)
{
debugLevel = level;
debugOut = out;
}
/* get the port that we're supposed to be listening on
*/
public int getPort ()
{
return thisPort;
}
/* return whether or not the socket is currently open
*/
public boolean isRunning ()
{
if (server == null)
return false;
else
return true;
}
/* closeSocket will close the open ServerSocket; use this
* to halt a running jProxy thread
*/
public void closeSocket ()
{
try {
// close the open server socket
server.close();
// send it a message to make it stop waiting immediately
// (not really necessary)
/*Socket s = new Socket("localhost", thisPort);
OutputStream os = s.getOutputStream();
os.write((byte)0);
os.close();
s.close();*/
} catch(Exception e) {
if (debugLevel > 0)
debugOut.println(e);
}
server = null;
}
public void run()
{
try {
// create a server socket, and loop forever listening for
// client connections
server = new ServerSocket(thisPort);
while (true)
{
Socket client = server.accept();
ProxyThread t = new ProxyThread(client, doSocks, sProxy);
//t.setDebug(debugLevel, debugOut);
//t.setTimeout(ptTimeout);
t.start();
}
} catch (Exception e) {
if (debugLevel > 0)
debugOut.println("jProxy Thread error: " + e);
}
closeSocket();
}
}
/*
* The ProxyThread will take an HTTP request from the client
* socket and send it to either the server that the client is
* trying to contact, or another proxy server
*/
class ProxyThread extends Thread
{
private Socket pSocket;
private String fwdServer = "";
private int fwdPort = 0;
private int debugLevel = 0;
private PrintStream debugOut = System.out;
// the socketTimeout is used to time out the connection to
// the remote server after a certain period of inactivity;
// the value is in milliseconds -- use zero if you don't want
// a timeout
public static final int DEFAULT_TIMEOUT = 20 * 1000;
private int socketTimeout = DEFAULT_TIMEOUT;
private boolean doSocks = false;
private static Socks5Proxy sProxy = null;
public ProxyThread(Socket s, boolean doSocks, Socks5Proxy sProxy)
{
pSocket = s;
this.sProxy = sProxy;
this.doSocks = doSocks;
}
public ProxyThread(Socket s, String proxy, int port)
{
pSocket = s;
fwdServer = proxy;
fwdPort = port;
}
public void setTimeout (int timeout)
{
// assume that the user will pass the timeout value
// in seconds (because that's just more intuitive)
socketTimeout = timeout * 1000;
}
public void setDebug (int level, PrintStream out)
{
debugLevel = level;
debugOut = out;
}
public void run()
{
try
{
long startTime = System.currentTimeMillis();
// client streams (make sure you're using streams that use
// byte arrays, so things like GIF and JPEG files and file
// downloads will transfer properly)
BufferedInputStream clientIn = new BufferedInputStream(pSocket.getInputStream());
BufferedOutputStream clientOut = new BufferedOutputStream(pSocket.getOutputStream());
// the socket to the remote server
Socket server = null;
// other variables
byte[] request = null;
byte[] response = null;
int requestLength = 0;
int responseLength = 0;
int pos = -1;
StringBuffer host = new StringBuffer("");
String hostName = "";
int hostPort = 80;
// get the header info (the web browser won't disconnect after
// it's sent a request, so make sure the waitForDisconnect
// parameter is false)
request = getHTTPData(clientIn, host, false);
requestLength = Array.getLength(request);
// separate the host name from the host port, if necessary
// (like if it's "servername:8000")
hostName = host.toString();
pos = hostName.indexOf(":");
if (pos > 0)
{
try { hostPort = Integer.parseInt(hostName.substring(pos + 1));
} catch (Exception e) { }
hostName = hostName.substring(0, pos);
}
// either forward this request to another proxy server or
// send it straight to the Host
try
{
if (!doSocks)
{
if ((fwdServer.length() > 0) && (fwdPort > 0))
{
server = new Socket(fwdServer, fwdPort);
} else {
server = new Socket(hostName, hostPort);
}
}
else
{
server = new SocksSocket(sProxy,hostName, hostPort);
}
} catch (Exception e) {
// tell the client there was an error
String errMsg = "HTTP/1.0 500\nContent Type: text/plain\n\n" +
"Error connecting to the server:\n" + e + "\n";
clientOut.write(errMsg.getBytes(), 0, errMsg.length());
}
if (server != null)
{
server.setSoTimeout(socketTimeout);
BufferedInputStream serverIn = new BufferedInputStream(server.getInputStream());
BufferedOutputStream serverOut = new BufferedOutputStream(server.getOutputStream());
// send the request out
serverOut.write(request, 0, requestLength);
serverOut.flush();
// and get the response; if we're not at a debug level that
// requires us to return the data in the response, just stream
// it back to the client to save ourselves from having to
// create and destroy an unnecessary byte array. Also, we
// should set the waitForDisconnect parameter to 'true',
// because some servers (like Google) don't always set the
// Content-Length header field, so we have to listen until
// they decide to disconnect (or the connection times out).
if (debugLevel > 1)
{
response = getHTTPData(serverIn, true);
responseLength = Array.getLength(response);
} else {
responseLength = streamHTTPData(serverIn, clientOut, true);
}
serverIn.close();
serverOut.close();
}
// send the response back to the client, if we haven't already
if (debugLevel > 1)
clientOut.write(response, 0, responseLength);
// if the user wants debug info, send them debug info; however,
// keep in mind that because we're using threads, the output won't
// necessarily be synchronous
if (debugLevel > 0)
{
long endTime = System.currentTimeMillis();
debugOut.println("Request from " + pSocket.getInetAddress().getHostAddress() +
" on Port " + pSocket.getLocalPort() +
" to host " + hostName + ":" + hostPort +
"\n (" + requestLength + " bytes sent, " +
responseLength + " bytes returned, " +
Long.toString(endTime - startTime) + " ms elapsed)");
debugOut.flush();
}
if (debugLevel > 1)
{
debugOut.println("REQUEST:\n" + (new String(request)));
debugOut.println("RESPONSE:\n" + (new String(response)));
debugOut.flush();
}
// close all the client streams so we can listen again
clientOut.close();
clientIn.close();
pSocket.close();
} catch (Exception e) {
if (debugLevel > 0)
debugOut.println("Error in ProxyThread: " + e);
//e.printStackTrace();
}
}
private byte[] getHTTPData (InputStream in, boolean waitForDisconnect)
{
// get the HTTP data from an InputStream, and return it as
// a byte array
// the waitForDisconnect parameter tells us what to do in case
// the HTTP header doesn't specify the Content-Length of the
// transmission
StringBuffer foo = new StringBuffer("");
return getHTTPData(in, foo, waitForDisconnect);
}
private byte[] getHTTPData (InputStream in, StringBuffer host, boolean waitForDisconnect)
{
// get the HTTP data from an InputStream, and return it as
// a byte array, and also return the Host entry in the header,
// if it's specified -- note that we have to use a StringBuffer
// for the 'host' variable, because a String won't return any
// information when it's used as a parameter like that
ByteArrayOutputStream bs = new ByteArrayOutputStream();
streamHTTPData(in, bs, host, waitForDisconnect);
return bs.toByteArray();
}
private int streamHTTPData (InputStream in, OutputStream out, boolean waitForDisconnect)
{
StringBuffer foo = new StringBuffer("");
return streamHTTPData(in, out, foo, waitForDisconnect);
}
private int streamHTTPData (InputStream in, OutputStream out,
StringBuffer host, boolean waitForDisconnect)
{
// get the HTTP data from an InputStream, and send it to
// the designated OutputStream
StringBuffer header = new StringBuffer("");
String data = "";
int responseCode = 200;
int contentLength = 0;
int pos = -1;
int byteCount = 0;
try
{
// get the first line of the header, so we know the response code
data = readLine(in);
if (data != null)
{
header.append(data + "\r\n");
pos = data.indexOf(" ");
if ((data.toLowerCase().startsWith("http")) &&
(pos >= 0) && (data.indexOf(" ", pos+1) >= 0))
{
String rcString = data.substring(pos+1, data.indexOf(" ", pos+1));
try
{
responseCode = Integer.parseInt(rcString);
} catch (Exception e) {
if (debugLevel > 0)
debugOut.println("Error parsing response code " + rcString);
}
}
}
// get the rest of the header info
while ((data = readLine(in)) != null)
{
// the header ends at the first blank line
if (data.length() == 0)
break;
header.append(data + "\r\n");
// check for the Host header
pos = data.toLowerCase().indexOf("host:");
if (pos >= 0)
{
host.setLength(0);
host.append(data.substring(pos + 5).trim());
}
// check for the Content-Length header
pos = data.toLowerCase().indexOf("content-length:");
if (pos >= 0)
contentLength = Integer.parseInt(data.substring(pos + 15).trim());
}
// add a blank line to terminate the header info
header.append("\r\n");
// convert the header to a byte array, and write it to our stream
out.write(header.toString().getBytes(), 0, header.length());
// if the header indicated that this was not a 200 response,
// just return what we've got if there is no Content-Length,
// because we may not be getting anything else
if ((responseCode != 200) && (contentLength == 0))
{
out.flush();
return header.length();
}
// get the body, if any; we try to use the Content-Length header to
// determine how much data we're supposed to be getting, because
// sometimes the client/server won't disconnect after sending us
// information...
if (contentLength > 0)
waitForDisconnect = false;
if ((contentLength > 0) || (waitForDisconnect))
{
try {
byte[] buf = new byte[4096];
int bytesIn = 0;
while ( ((byteCount < contentLength) || (waitForDisconnect))
&& ((bytesIn = in.read(buf)) >= 0) )
{
out.write(buf, 0, bytesIn);
byteCount += bytesIn;
}
} catch (Exception e) {
String errMsg = "Error getting HTTP body: " + e;
if (debugLevel > 0)
debugOut.println(errMsg);
//bs.write(errMsg.getBytes(), 0, errMsg.length());
}
}
} catch (Exception e) {
if (debugLevel > 0)
debugOut.println("Error getting HTTP data: " + e);
}
//flush the OutputStream and return
try { out.flush(); } catch (Exception e) {}
return (header.length() + byteCount);
}
private String readLine (InputStream in)
{
// reads a line of text from an InputStream
StringBuffer data = new StringBuffer("");
int c;
try
{
// if we have nothing to read, just return null
in.mark(1);
if (in.read() == -1)
return null;
else
in.reset();
while ((c = in.read()) >= 0)
{
// check for an end-of-line character
if ((c == 0) || (c == 10) || (c == 13))
break;
else
data.append((char)c);
}
// deal with the case where the end-of-line terminator is \r\n
if (c == 13)
{
in.mark(1);
if (in.read() != 10)
in.reset();
}
} catch (Exception e) {
if (debugLevel > 0)
debugOut.println("Error getting header: " + e);
}
// and return what we have
return data.toString();
}
}

View File

@ -0,0 +1,129 @@
/* Copyright (c) 2009-2011, Nathan Freitas, The Guardian Project - http://openideals.com/guardian */
/* See LICENSE for licensing information */
/** SOCKS aware echo client*/
package org.torproject.android;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import net.sourceforge.jsocks.socks.*;
public class SocksClient implements Runnable {
private int port;
private InetAddress hostIP;
private Socket ss;
private InputStream in;
private OutputStream out;
private static final int BUF_SIZE = 1024;
public SocksClient(String host,int port)
throws IOException,UnknownHostException,SocksException{
this.port = port;
ss = new SocksSocket(host, port);
out = ss.getOutputStream();
in = ss.getInputStream();
System.out.println("Connected...");
System.out.println("TO: "+host+":"+port);
System.out.println("ViaProxy: "+ss.getLocalAddress().getHostAddress()
+":"+ss.getLocalPort());
}
public void close()throws IOException{
ss.close();
}
public void send(String s) throws IOException{
out.write(s.getBytes());
}
public void run(){
byte[] buf = new byte[1024];
int bytes_read;
try{
while((bytes_read = in.read(buf)) > 0){
System.out.write(buf,0,bytes_read);
}
}catch(IOException io_ex){
io_ex.printStackTrace();
}
}
public static void usage(){
System.err.print(
"Usage: java SocksTest host port [socksHost socksPort]\n");
}
public static void main(String args[]){
int port;
String host;
int proxyPort;
String proxyHost;
if(args.length > 1 && args.length < 5){
try{
host = args[0];
port = Integer.parseInt(args[1]);
proxyPort =(args.length > 3)? Integer.parseInt(args[3])
: TorConstants.PORT_SOCKS;
host = args[0];
proxyHost =(args.length > 2)? args[2]
: TorConstants.IP_LOCALHOST;
Proxy.setDefaultProxy(proxyHost,proxyPort,"KOUKY001");
//Proxy.setDefaultProxy(proxyHost,proxyPort);
InetRange inetRange = new InetRange();
inetRange.add(InetAddress.getByName("localhost"));
Proxy.getDefaultProxy().setDirect(inetRange);
SocksClient st = new SocksClient(host,port);
Thread thread = new Thread(st);
thread.start();
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
String s;
s = in.readLine();
while(s != null){
st.send(s+"\r\n");
//try{
//Thread.currentThread().sleep(10);
//}catch(InterruptedException i_ex){
//}
s = in.readLine();
}
st.close();
System.exit(1);
}catch(SocksException s_ex){
System.err.println("SocksException:"+s_ex);
s_ex.printStackTrace();
System.exit(1);
}catch(IOException io_ex){
io_ex.printStackTrace();
System.exit(1);
}catch(NumberFormatException num_ex){
usage();
num_ex.printStackTrace();
System.exit(1);
}
}else{
usage();
}
}
}//End of class

View File

@ -0,0 +1,158 @@
/* Copyright (c) 2009-2011, Nathan Freitas, The Guardian Project - http://openideals.com/guardian */
/* See LICENSE for licensing information */
package org.torproject.android;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import android.util.Log;
public class TorBinaryInstaller implements TorConstants {
private final static String LOG_TAG = "Tor";
public TorBinaryInstaller ()
{
}
/*
* Start the binary installation if the file doesn't exist or is forced
*/
public void start (boolean force)
{
boolean binaryExists = new File(TOR_BINARY_INSTALL_PATH).exists();
Log.i(LOG_TAG,"Tor binary exists=" + binaryExists);
if (!binaryExists || force)
installFromZip ();
}
/*
* Extract the Tor binary from the APK file using ZIP
*/
private void installFromZip ()
{
try
{
ZipFile zip = new ZipFile(APK_PATH);
ZipEntry zipen = zip.getEntry(TOR_BINARY_ZIP_KEY);
streamToFile(zip.getInputStream(zipen),TOR_BINARY_INSTALL_PATH);
zipen = zip.getEntry(TORRC_ZIP_KEY);
streamToFile(zip.getInputStream(zipen),TORRC_INSTALL_PATH);
zip.close();
}
catch (IOException ioe)
{
Log.i(LOG_TAG,"unable to unzip tor binary from apk",ioe);
}
}
/*
* Write the inputstream contents to the file
*/
private static void streamToFile(InputStream stm, String targetFilename)
{
FileOutputStream stmOut = null;
byte[] buffer = new byte[FILE_WRITE_BUFFER_SIZE];
int bytecount;
File outFile = new File(targetFilename);
try {
outFile.createNewFile();
stmOut = new FileOutputStream(outFile);
}
catch (java.io.IOException e)
{
Log.i(LOG_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.i(LOG_TAG,"Error writing output file '" + targetFilename + "': " + e.toString());
return;
}
}
//copy the file from inputstream to File output - alternative impl
public void copyFile (InputStream is, File outputFile)
{
try {
outputFile.createNewFile();
DataOutputStream out = new DataOutputStream(new FileOutputStream(outputFile));
DataInputStream in = new DataInputStream(is);
int b;
byte[] data = new byte[1024];
while ((b = in.read(data)) != -1) {
out.write(data);
}
//
out.flush();
out.close();
in.close();
// chmod?
} catch (IOException ex) {
Log.e(LOG_TAG, "error copying binary", ex);
}
}
}

View File

@ -0,0 +1,59 @@
/* Copyright (c) 2009-2011, Nathan Freitas, The Guardian Project - http://openideals.com/guardian */
/* See LICENSE for licensing information */
package org.torproject.android;
public interface TorConstants {
//home directory of Android application
public final static String TOR_HOME = "/data/data/org.torproject.android/";
//name of the tor C binary
public final static String TOR_BINARY_ASSET_KEY = "tor";
//path to install the Tor binary too
public final static String TOR_BINARY_INSTALL_PATH = TOR_HOME + TOR_BINARY_ASSET_KEY;
//key of the tor binary in the Zip file
public final static String TOR_BINARY_ZIP_KEY = "assets/" + TOR_BINARY_ASSET_KEY;
//torrc file name
public final static String TORRC_ASSET_KEY = "torrc";
//path to install torrc to within the android app data folder
public final static String TORRC_INSTALL_PATH = TOR_HOME + TORRC_ASSET_KEY;
//key of the torrc file in the Zip file
public final static String TORRC_ZIP_KEY = "assets/" + TORRC_ASSET_KEY;
//where to send the notices log
public final static String TOR_LOG_PATH = TOR_HOME + "notices.log";
//how to launch tor
public final static String TOR_COMMAND_LINE_ARGS = "-f " + TORRC_INSTALL_PATH;
//various console cmds
public final static String SHELL_CMD_CHMOD = "/system/bin/chmod";
public final static String SHELL_CMD_KILLALL = "/system/bin/kill";
public final static String SHELL_CMD_RM = "/system/bin/rm";
public final static String SHELL_CMD_PS = "ps";
public final static String CHMOD_EXE_VALUE = "777";
//path of the installed APK file
public final static String APK_PATH = "/data/app/org.torproject.android.apk";
//path to check Tor against
public final static String URL_TOR_CHECK = "http://check.torproject.org";
public final static int FILE_WRITE_BUFFER_SIZE = 2048;
//HTTP Proxy server port
public final static int PORT_HTTP = 8118; //just like Privoxy!
//Socks port client connects to, server is the Tor binary
public final static int PORT_SOCKS = 9050;
//what is says!
public final static String IP_LOCALHOST = "127.0.0.1";
}

View File

@ -0,0 +1,337 @@
/* Copyright (c) 2009-2011, Nathan Freitas, The Guardian Project - http://openideals.com/guardian */
/* See LICENSE for licensing information */
package org.torproject.android;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class TorControlPanel extends Activity implements OnClickListener, TorConstants
{
private final static String LOG_TAG = "Tor";
private Intent torService = null;
private boolean updateLog = false;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
showMain();
}
/* (non-Javadoc)
* @see android.app.Activity#onPause()
*/
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
/* (non-Javadoc)
* @see android.app.Activity#onResume()
*/
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
setUIState ();
}
/* (non-Javadoc)
* @see android.app.Activity#onStart()
*/
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
setUIState ();
}
/* (non-Javadoc)
* @see android.app.Activity#onStop()
*/
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
}
/*
* Show the main form UI
*/
private void showMain ()
{
updateLog = false;
setContentView(R.layout.layout_main);
((Button)findViewById(R.id.btnStart)).setOnClickListener(this);
((Button)findViewById(R.id.btnLog)).setOnClickListener(this);
((Button)findViewById(R.id.btnSettings)).setOnClickListener(this);
setUIState ();
}
/*
* Show the message log UI
*/
private void showMessageLog ()
{
setContentView(R.layout.layout_log);
((Button)findViewById(R.id.btnLogClose)).setOnClickListener(this);
updateLog = true;
Thread thread = new Thread ()
{
public void run ()
{
while (updateLog)
{
handler.sendEmptyMessage(0);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
thread.start();
}
/*
* Load the Tor log and display it in a text field
*/
private void updateMessageLog ()
{
TextView tvLog = (TextView)findViewById(R.id.messageLog);
String output = loadLogFile(TOR_LOG_PATH);
tvLog.setText(output);
}
/*
* Handle to reload Tor debug log every few seconds while viewing it
*/
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
updateMessageLog ();
}
};
/*
* Load the basic settings application to display torrc
* TODO: these needs to be improved into an actual form GUI
*/
private void showSettings ()
{
setContentView(R.layout.layout_settings);
TextView tvLog = (TextView)findViewById(R.id.textSettings);
((Button)findViewById(R.id.btnSettingsClose)).setOnClickListener(this);
String output = loadLogFile(TORRC_INSTALL_PATH);
tvLog.setText(output);
}
/*
* Set the state of the running/not running graphic and label
*/
public void setUIState ()
{
TextView lblStatus = (TextView)findViewById(R.id.lblStatus);
ImageView imgStatus = (ImageView)findViewById(R.id.imgStatus);
Button btnStart = (Button)findViewById(R.id.btnStart);
if (TorService.isRunning())
{
btnStart.setText("Stop Tor");
imgStatus.setImageResource(R.drawable.toron);
lblStatus.setText("Tor is running");
}
else
{
btnStart.setText("Start Tor");
imgStatus.setImageResource(R.drawable.toroff);
lblStatus.setText("Tor is not running");
}
}
/*
* (non-Javadoc)
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
public void onClick(View view) {
// the start button
if (view.getId()==R.id.btnStart)
{
//if Tor binary is not running, then start the service up
if (!TorService.isRunning())
{
torService = new Intent(this, TorService.class);
torService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
TorService.setActivity(this);
startService(torService);
}
else
{
if (torService == null)
torService = new Intent(this, TorService.class);
TorService.setActivity(this);
stopService(torService);
}
//update the UI
setUIState ();
}
else if (view.getId()==R.id.btnLog)
{
showMessageLog();
}
else if (view.getId()==R.id.btnSettings)
{
showSettings();
}
else if (view.getId()==R.id.btnLogClose || view.getId()==R.id.btnSettingsClose)
{
showMain();
}
}
/*
* Load the log file text
*/
public static String loadLogFile (String path)
{
String line = null;
StringBuffer out = new StringBuffer();
try {
BufferedReader reader = new BufferedReader((new FileReader(new File(path))));
while ((line = reader.readLine()) != null)
{
out.append(line);
out.append('\n');
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return out.toString();
}
/*
* Get the last line of the log file for status display
*/
public static String getLastLine (String path)
{
String line = null;
String lastLine = null;
try {
BufferedReader reader = new BufferedReader((new FileReader(new File(path))));
while ((line = reader.readLine()) != null)
{
lastLine = line;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return lastLine;
}
}

View File

@ -0,0 +1,391 @@
/* Copyright (c) 2009-2011, Nathan Freitas, The Guardian Project - http://openideals.com/guardian */
/* See LICENSE for licensing information */
package org.torproject.android;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import net.sourceforge.jsocks.socks.Proxy;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class TorService extends Service implements TorConstants
{
private static TorControlPanel ACTIVITY = null;
private final static String TAG = "Tor";
private static HttpProxy webProxy = null;
private static Process procTor = null;
/** Called when the activity is first created. */
@Override
public void onCreate() {
super.onCreate();
}
public static boolean isRunning ()
{
int procId = findProcessId(TorConstants.TOR_BINARY_INSTALL_PATH);
return (procId != -1);
}
/* (non-Javadoc)
* @see android.app.Service#onRebind(android.content.Intent)
*/
@Override
public void onRebind(Intent intent) {
// TODO Auto-generated method stub
super.onRebind(intent);
Log.i(TAG,"on rebind");
}
/* (non-Javadoc)
* @see android.app.Service#onStart(android.content.Intent, int)
*/
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Log.i(TAG,"on start");
startService();
}
private void startService ()
{
Log.i(TAG,"Tor thread started");
initTor();
setupWebProxy(true);
}
public void onDestroy ()
{
killTorProcess ();
setupWebProxy(false);
}
public static void setActivity(TorControlPanel activity) {
ACTIVITY = activity;
}
private void setupWebProxy (boolean enabled)
{
if (enabled)
{
if (webProxy == null)
{
Log.i(TAG,"Setting up Web Proxy on port 8888");
//httpd s
webProxy = new HttpProxy(PORT_HTTP);
webProxy.setDoSocks(true);
webProxy.start();
//socks
try
{
Proxy.setDefaultProxy(IP_LOCALHOST,PORT_SOCKS);
}
catch (Exception e)
{
Log.w(TAG,e.getMessage());
}
//Settings.System.putString(getContentResolver(), Settings.System.HTTP_PROXY, proxySetting);//enable proxy
// Settings.Secure.putString(getContentResolver(), Settings.Secure.HTTP_PROXY, proxySetting);//enable proxy
}
else
{
webProxy.setDoSocks(true);
Log.i(TAG,"Web Proxy already running...");
}
}
else
{
Log.i(TAG,"Turning off Socks/Tor routing on Web Proxy");
if (webProxy != null)
{
showToast("Tor is disabled - browsing is not anonymous!");
webProxy.setDoSocks(false);
}
}
}
private void killTorProcess ()
{
//doCommand(SHELL_CMD_KILLALL, CHMOD_EXE_VALUE, TOR_BINARY_INSTALL_PATH);
if (procTor != null)
{
Log.i(TAG,"shutting down Tor process...");
procTor.destroy();
try {
procTor.waitFor();
}
catch(Exception e)
{
e.printStackTrace();
}
int exitStatus = procTor.exitValue();
Log.i(TAG,"Tor exit: " + exitStatus);
procTor = null;
}
int procId = findProcessId(TorConstants.TOR_BINARY_INSTALL_PATH);
if (procId != -1)
{
Log.i(TAG,"Found Tor PID=" + procId + " - killing now...");
doCommand(SHELL_CMD_KILLALL, procId + "");
}
if (ACTIVITY != null)
((TorControlPanel)ACTIVITY).setUIState();
}
private void showToast (String msg)
{
Toast toast = Toast.makeText(ACTIVITY, msg, Toast.LENGTH_LONG);
toast.show();
}
public void initTor ()
{
try {
boolean binaryExists = new File(TOR_BINARY_INSTALL_PATH).exists();
if (!binaryExists)
{
TorBinaryInstaller installer = new TorBinaryInstaller();
installer.start(false);
binaryExists = new File(TOR_BINARY_INSTALL_PATH).exists();
if (binaryExists)
{
showToast("Tor binary installed!");
}
else
{
showToast("Tor binary install FAILED!");
return;
}
}
Log.i(TAG,"Setting permission on Tor binary");
doCommand(SHELL_CMD_CHMOD, CHMOD_EXE_VALUE + ' ' + TOR_BINARY_INSTALL_PATH);
killTorProcess ();
doCommand(SHELL_CMD_RM,TOR_LOG_PATH);
Log.i(TAG,"Starting tor process");
procTor = doCommand(TOR_BINARY_INSTALL_PATH, TOR_COMMAND_LINE_ARGS);
//Log.i(TAG,"Tor process id=" + procTor.);
showToast("Tor is starting up...");
((TorControlPanel)ACTIVITY).setUIState();
} catch (Exception e) {
Log.w(TAG,"unable to start Tor Process",e);
e.printStackTrace();
}
}
private static void logStream (InputStream is)
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
try {
while ((line = reader.readLine()) != null)
{
Log.i(TAG, line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public static int findProcessId(String command)
{
int procId = -1;
Runtime r = Runtime.getRuntime();
Process procPs = null;
try {
procPs = r.exec(SHELL_CMD_PS);
BufferedReader reader = new BufferedReader(new InputStreamReader(procPs.getInputStream()));
String line = null;
while ((line = reader.readLine())!=null)
{
if (line.indexOf(command)!=-1)
{
StringTokenizer st = new StringTokenizer(line," ");
st.nextToken(); //proc owner
procId = Integer.parseInt(st.nextToken().trim());
break;
}
}
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
}
return procId;
}
public Process doCommand(String command, String arg1)
{
Runtime r = Runtime.getRuntime();
Process child = null;
try {
if(child != null) {
child.destroy();
child = null;
}
child = r.exec(command + ' ' + arg1);
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
}
return child;
}
/*
public static String doCommand(String command, String arg0, String arg1, boolean logOutput) {
try {
// android.os.Exec is not included in android.jar so we need to use reflection.
Class execClass = Class.forName("android.os.Exec");
Method createSubprocess = execClass.getMethod("createSubprocess",
String.class, String.class, String.class, int[].class);
Method waitFor = execClass.getMethod("waitFor", int.class);
// Executes the command.
// NOTE: createSubprocess() is asynchronous.
int[] pid = new int[1];
FileDescriptor fd = (FileDescriptor)createSubprocess.invoke(
null, command, arg0, arg1, pid);
StringBuffer output = new StringBuffer();
if (logOutput)
{
// Reads stdout.
// NOTE: You can write to stdin of the command using new FileOutputStream(fd).
FileInputStream in = new FileInputStream(fd);
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
try {
String line;
while ((line = reader.readLine()) != null) {
output.append(line);
output.append('\n');
}
} catch (IOException e) {
// It seems IOException is thrown when it reaches EOF.
Log.e(TAG, "error reading output file", e);
}
// Waits for the command to finish.
waitFor.invoke(null, pid[0]);
}
// send output to the textbox
return output.toString();
}
catch (Exception e)
{
Log.i(TAG, "unable to execute command",e);
e.printStackTrace();
return null;
}
}*/
}