[or-cvs] r20811: {} First check-in of Orbot: the Onion Routing Robot (aka Tor on (in projects/android/trunk: . Orbot Orbot/.settings Orbot/assets Orbot/res Orbot/res/drawable Orbot/res/layout Orbot/res/values Orbot/src Orbot/src/org Orbot/src/org/torproject Orbot/src/org/torproject/android)

n8fr8 at seul.org n8fr8 at seul.org
Wed Oct 21 23:17:45 UTC 2009


Author: n8fr8
Date: 2009-10-21 19:17:45 -0400 (Wed, 21 Oct 2009)
New Revision: 20811

Added:
   projects/android/trunk/Orbot/
   projects/android/trunk/Orbot/.classpath
   projects/android/trunk/Orbot/.project
   projects/android/trunk/Orbot/.settings/
   projects/android/trunk/Orbot/.settings/.jsdtscope
   projects/android/trunk/Orbot/.settings/org.eclipse.wst.jsdt.ui.superType.container
   projects/android/trunk/Orbot/.settings/org.eclipse.wst.jsdt.ui.superType.name
   projects/android/trunk/Orbot/AUTHORS
   projects/android/trunk/Orbot/AndroidManifest.xml
   projects/android/trunk/Orbot/LICENSE
   projects/android/trunk/Orbot/README
   projects/android/trunk/Orbot/assets/
   projects/android/trunk/Orbot/assets/tor
   projects/android/trunk/Orbot/assets/torrc
   projects/android/trunk/Orbot/bcdroid.manifest
   projects/android/trunk/Orbot/bin/
   projects/android/trunk/Orbot/default.properties
   projects/android/trunk/Orbot/gen/
   projects/android/trunk/Orbot/jsocks.jar
   projects/android/trunk/Orbot/res/
   projects/android/trunk/Orbot/res/drawable/
   projects/android/trunk/Orbot/res/drawable/icon.png
   projects/android/trunk/Orbot/res/drawable/tor.png
   projects/android/trunk/Orbot/res/drawable/toroff.png
   projects/android/trunk/Orbot/res/drawable/toron.png
   projects/android/trunk/Orbot/res/layout/
   projects/android/trunk/Orbot/res/layout/layout_log.xml
   projects/android/trunk/Orbot/res/layout/layout_main.xml
   projects/android/trunk/Orbot/res/layout/layout_settings.xml
   projects/android/trunk/Orbot/res/values/
   projects/android/trunk/Orbot/res/values/strings.xml
   projects/android/trunk/Orbot/src/
   projects/android/trunk/Orbot/src/org/
   projects/android/trunk/Orbot/src/org/torproject/
   projects/android/trunk/Orbot/src/org/torproject/android/
   projects/android/trunk/Orbot/src/org/torproject/android/HttpProxy.java
   projects/android/trunk/Orbot/src/org/torproject/android/SocksClient.java
   projects/android/trunk/Orbot/src/org/torproject/android/TorBinaryInstaller.java
   projects/android/trunk/Orbot/src/org/torproject/android/TorConstants.java
   projects/android/trunk/Orbot/src/org/torproject/android/TorControlPanel.java
   projects/android/trunk/Orbot/src/org/torproject/android/TorService.java
Log:
First check-in of Orbot: the Onion Routing Robot (aka Tor on Android)

Added: projects/android/trunk/Orbot/.classpath
===================================================================
--- projects/android/trunk/Orbot/.classpath	                        (rev 0)
+++ projects/android/trunk/Orbot/.classpath	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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>

Added: projects/android/trunk/Orbot/.project
===================================================================
--- projects/android/trunk/Orbot/.project	                        (rev 0)
+++ projects/android/trunk/Orbot/.project	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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>

Added: projects/android/trunk/Orbot/.settings/.jsdtscope
===================================================================
--- projects/android/trunk/Orbot/.settings/.jsdtscope	                        (rev 0)
+++ projects/android/trunk/Orbot/.settings/.jsdtscope	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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>

Added: projects/android/trunk/Orbot/.settings/org.eclipse.wst.jsdt.ui.superType.container
===================================================================
--- projects/android/trunk/Orbot/.settings/org.eclipse.wst.jsdt.ui.superType.container	                        (rev 0)
+++ projects/android/trunk/Orbot/.settings/org.eclipse.wst.jsdt.ui.superType.container	2009-10-21 23:17:45 UTC (rev 20811)
@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file

Added: projects/android/trunk/Orbot/.settings/org.eclipse.wst.jsdt.ui.superType.name
===================================================================
--- projects/android/trunk/Orbot/.settings/org.eclipse.wst.jsdt.ui.superType.name	                        (rev 0)
+++ projects/android/trunk/Orbot/.settings/org.eclipse.wst.jsdt.ui.superType.name	2009-10-21 23:17:45 UTC (rev 20811)
@@ -0,0 +1 @@
+Window
\ No newline at end of file

Added: projects/android/trunk/Orbot/AUTHORS
===================================================================
--- projects/android/trunk/Orbot/AUTHORS	                        (rev 0)
+++ projects/android/trunk/Orbot/AUTHORS	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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 at freitas.net> developed the primary
+Android application and managed the porting of Tor to Android.
+
+
+Contributors:
+-------------
+Jack Appelbaum <jake at 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 at 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.
\ No newline at end of file

Added: projects/android/trunk/Orbot/AndroidManifest.xml
===================================================================
--- projects/android/trunk/Orbot/AndroidManifest.xml	                        (rev 0)
+++ projects/android/trunk/Orbot/AndroidManifest.xml	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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> 
\ No newline at end of file

Added: projects/android/trunk/Orbot/LICENSE
===================================================================
--- projects/android/trunk/Orbot/LICENSE	                        (rev 0)
+++ projects/android/trunk/Orbot/LICENSE	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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 at 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 at 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 at 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 at 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 at 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 at 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 at 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.
+===============================================================================
+
+
+
+
+

Added: projects/android/trunk/Orbot/README
===================================================================
--- projects/android/trunk/Orbot/README	                        (rev 0)
+++ projects/android/trunk/Orbot/README	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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 */

Added: projects/android/trunk/Orbot/assets/tor
===================================================================
(Binary files differ)


Property changes on: projects/android/trunk/Orbot/assets/tor
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + application/octet-stream

Added: projects/android/trunk/Orbot/assets/torrc
===================================================================
--- projects/android/trunk/Orbot/assets/torrc	                        (rev 0)
+++ projects/android/trunk/Orbot/assets/torrc	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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 *:*
+

Added: projects/android/trunk/Orbot/bcdroid.manifest
===================================================================
--- projects/android/trunk/Orbot/bcdroid.manifest	                        (rev 0)
+++ projects/android/trunk/Orbot/bcdroid.manifest	2009-10-21 23:17:45 UTC (rev 20811)
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Sealed: true
+

Added: projects/android/trunk/Orbot/default.properties
===================================================================
--- projects/android/trunk/Orbot/default.properties	                        (rev 0)
+++ projects/android/trunk/Orbot/default.properties	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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

Added: projects/android/trunk/Orbot/jsocks.jar
===================================================================
(Binary files differ)


Property changes on: projects/android/trunk/Orbot/jsocks.jar
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: projects/android/trunk/Orbot/res/drawable/icon.png
===================================================================
(Binary files differ)


Property changes on: projects/android/trunk/Orbot/res/drawable/icon.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: projects/android/trunk/Orbot/res/drawable/tor.png
===================================================================
(Binary files differ)


Property changes on: projects/android/trunk/Orbot/res/drawable/tor.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: projects/android/trunk/Orbot/res/drawable/toroff.png
===================================================================
(Binary files differ)


Property changes on: projects/android/trunk/Orbot/res/drawable/toroff.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: projects/android/trunk/Orbot/res/drawable/toron.png
===================================================================
(Binary files differ)


Property changes on: projects/android/trunk/Orbot/res/drawable/toron.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: projects/android/trunk/Orbot/res/layout/layout_log.xml
===================================================================
--- projects/android/trunk/Orbot/res/layout/layout_log.xml	                        (rev 0)
+++ projects/android/trunk/Orbot/res/layout/layout_log.xml	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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>

Added: projects/android/trunk/Orbot/res/layout/layout_main.xml
===================================================================
--- projects/android/trunk/Orbot/res/layout/layout_main.xml	                        (rev 0)
+++ projects/android/trunk/Orbot/res/layout/layout_main.xml	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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>
+

Added: projects/android/trunk/Orbot/res/layout/layout_settings.xml
===================================================================
--- projects/android/trunk/Orbot/res/layout/layout_settings.xml	                        (rev 0)
+++ projects/android/trunk/Orbot/res/layout/layout_settings.xml	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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>

Added: projects/android/trunk/Orbot/res/values/strings.xml
===================================================================
--- projects/android/trunk/Orbot/res/values/strings.xml	                        (rev 0)
+++ projects/android/trunk/Orbot/res/values/strings.xml	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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>

Added: projects/android/trunk/Orbot/src/org/torproject/android/HttpProxy.java
===================================================================
--- projects/android/trunk/Orbot/src/org/torproject/android/HttpProxy.java	                        (rev 0)
+++ projects/android/trunk/Orbot/src/org/torproject/android/HttpProxy.java	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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();
+	}
+	
+}
+

Added: projects/android/trunk/Orbot/src/org/torproject/android/SocksClient.java
===================================================================
--- projects/android/trunk/Orbot/src/org/torproject/android/SocksClient.java	                        (rev 0)
+++ projects/android/trunk/Orbot/src/org/torproject/android/SocksClient.java	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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

Added: projects/android/trunk/Orbot/src/org/torproject/android/TorBinaryInstaller.java
===================================================================
--- projects/android/trunk/Orbot/src/org/torproject/android/TorBinaryInstaller.java	                        (rev 0)
+++ projects/android/trunk/Orbot/src/org/torproject/android/TorBinaryInstaller.java	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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);
+		}
+
+	}
+	
+	
+
+}

Added: projects/android/trunk/Orbot/src/org/torproject/android/TorConstants.java
===================================================================
--- projects/android/trunk/Orbot/src/org/torproject/android/TorConstants.java	                        (rev 0)
+++ projects/android/trunk/Orbot/src/org/torproject/android/TorConstants.java	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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";
+	
+}

Added: projects/android/trunk/Orbot/src/org/torproject/android/TorControlPanel.java
===================================================================
--- projects/android/trunk/Orbot/src/org/torproject/android/TorControlPanel.java	                        (rev 0)
+++ projects/android/trunk/Orbot/src/org/torproject/android/TorControlPanel.java	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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;
+	    	
+	    }
+	 
+	
+	
+	
+}
\ No newline at end of file

Added: projects/android/trunk/Orbot/src/org/torproject/android/TorService.java
===================================================================
--- projects/android/trunk/Orbot/src/org/torproject/android/TorService.java	                        (rev 0)
+++ projects/android/trunk/Orbot/src/org/torproject/android/TorService.java	2009-10-21 23:17:45 UTC (rev 20811)
@@ -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;
+		}
+	}*/
+	
+}
\ No newline at end of file



More information about the tor-commits mailing list