First check-in of Orbot: the Onion Routing Robot (aka Tor on Android)
svn:r20811
This commit is contained in:
parent
37fdee5e62
commit
b8b0afd44b
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -0,0 +1 @@
|
||||||
|
org.eclipse.wst.jsdt.launching.baseBrowserLibrary
|
|
@ -0,0 +1 @@
|
||||||
|
Window
|
|
@ -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.
|
|
@ -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>
|
|
@ -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.
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
Binary file not shown.
|
@ -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 *:*
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Manifest-Version: 1.0
|
||||||
|
Sealed: true
|
||||||
|
|
|
@ -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
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
|
@ -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>
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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";
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue