[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: Tor on Android



Looks like I should do a quick write up:

One caveat, I'm running Android 1.1 PLAT-RC16, which is an unreleased
testing version. However, I don't believe that anything pertinent has
changed.

1) Setup your phone for debugging.

Home -> Settings -> Applications -> Development. Check both "USB
debugging" and "Stay Awake".

2) Setup udev

See http://code.google.com/android/intro/develop-and-debug.html and
search the page for "udev". This is to make sure that the USB device
inodes get the correct permissions.

3) Download the SDK

http://code.google.com/android/intro/installing.html

Put the tools/ directory from the SDK in your $PATH. You'll need the
adb utility from there.

4) Plug your phone into a USB port on your computer

`adb devices` should list a single device.

5) Grab a full source release and build it

Follow http://source.android.com/download. It's a lot of downloading,
disk space and build time. If you aren't running an Intel x86 or
x86-64 build platform you might have some issues. If you are running
x86-64 you'll still have some issues. Many of them are covered on the
above page but one which I had was that my distro (Ubuntu 8.10)
doesn't seem to have 32-bit libreadline libraries.

I built a 32-bit libreadline from source (this is from memory only):
% export CC="gcc -m32"
% ./configure
% make
% sudo cp libreadline.so.5.2 libhistory.so.5.2 /usr/lib32
% sudo chmod a+rx /usr/lib32/libreadline.so.5.2 /usr/lib32/libhistory.so.5.2
% ldconfig (might setup the symlinks /usr/lib/libreadline.so for you,
otherwise, do it manually)

Hopefully you can do a successful `make` run with the android source.

6) Setup agcc

Once you have a source build, you should have an ARM cross-compiler in
mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin. The agcc[1]
script will give all the correct arguments to it to build binaries
with bionic etc. Put both agcc and ..../arm-eabi-4.3.1 in your $PATH.

[1] http://plausible.org/andy/agcc

7) Build a test binary

% cat > test.c <<EOF
#include <stdio.h>

int
main() {
  printf("hello android\n");
  return 0;
}
EOF

% agcc test.c
% file ./a.out

That should get you an ARM binary

8) Try running it

% adb push a.out /sqlite_stmt_journals
% adb shell
$ cd /sqlite_stmt_journals
$ ./a.out

/sqlite_stmt_journals is just a tmpfs filesystem that's easy to get to.

9) Build libevent

Download libevent

% export CC="agcc"
% ./configure --host=arm-eabi

I had to manually disable select support in config.h and remove
select.c (and everything else to do with select) from the Makefile
because bionic seems to be missing fd_mask structures. I also didn't
bother building anything in /test.

Hopefully you end up with libevent.a (probably in .libs). Copy it to
mydroid/out/target/product/generic/obj/lib.

10) Setup include paths

I added these lines to the list of include paths in agcc:

    "-I$DROID/external/libevent-1.4.9-stable",
    "-I$DROID/external/openssl/include",
    "-I$DROID/external/zlib",

The first is where I happened to build libevent. Your location may
vary. The other two are path of the standard source distribution.

11) Build tor

I used 0.2.0.32

Firstly, Android doesn't include deprecated OpenSSL functions, so add
a wrapper to src/common/crypto.c:

+++ tor-0.2.0.32-agl/src/common/crypto.c  2008-12-28 12:24:25.000000000 -0800
@@ -387,6 +387,37 @@
   tor_free(env);
 }

+RSA *RSA_generate_key(int bits, unsigned long e_value,
+             void (*callback)(int,int,void *), void *cb_arg)
+        {
+        BN_GENCB cb;
+        int i;
+        RSA *rsa = RSA_new();
+        BIGNUM *e = BN_new();
+
+        if(!rsa || !e) goto err;
+
+        /* The problem is when building with 8, 16, or 32 BN_ULONG,
+         * unsigned long can be larger */
+        for (i=0; i<(int)sizeof(unsigned long)*8; i++)
+                {
+                if (e_value & (1UL<<i))
+                        if (BN_set_bit(e,i) == 0)
+                                goto err;
+                }
+
+        BN_GENCB_set_old(&cb, callback, cb_arg);
+
+        if(RSA_generate_key_ex(rsa, bits, e, &cb)) {
+                BN_free(e);
+                return rsa;
+        }
+err:
+        if(e) BN_free(e);
+        if(rsa) RSA_free(rsa);
+        return 0;
+}
+

Then, the only other issues I had were with some odd namespace
collision with log.h. I'll include the diffs, although I didn't bother
pinning down the problem, I just worked around where it popped up:

--- tor-0.2.0.32/src/common/log.h   2008-02-26 11:56:29.000000000 -0800
+++ tor-0.2.0.32-agl/src/common/log.h  2008-12-28 12:02:17.000000000 -0800
@@ -11,7 +11,7 @@
  * \brief Headers for log.c
  **/

-#ifndef __LOG_H
+#ifndef __TOR_LOG_H
 #define LOG_H_ID "$Id: log.h 13412 2008-02-07 05:31:47Z nickm $"

 #include "compat.h"
@@ -180,6 +180,6 @@

 #endif /* !GNUC */

-# define __LOG_H
+# define __TOR_LOG_H
 #endif
--- tor-0.2.0.32/src/or/buffers.c   2008-11-20 14:14:26.000000000 -0800
+++ tor-0.2.0.32-agl/src/or/buffers.c  2008-12-28 12:03:08.000000000 -0800
@@ -14,6 +14,7 @@
  * memory, file descriptors, or TLS connections.
  **/
 #define BUFFERS_PRIVATE
+#include "src/common/log.h"
 #include "or.h"

 //#define PARANOIA
diff -ur tor-0.2.0.32/src/or/circuitbuild.c
tor-0.2.0.32-agl/src/or/circuitbuild.c
--- tor-0.2.0.32/src/or/circuitbuild.c 2008-09-23 14:00:43.000000000 -0700
+++ tor-0.2.0.32-agl/src/or/circuitbuild.c   2008-12-28 12:03:30.000000000 -0800
@@ -12,6 +12,7 @@
  * \brief The actual details of building circuits.
  **/

+#include "src/common/log.h"
 #include "or.h"

 /********* START VARIABLES **********/
Only in tor-0.2.0.32-agl/src/or: .deps
diff -ur tor-0.2.0.32/src/or/eventdns.c tor-0.2.0.32-agl/src/or/eventdns.c
--- tor-0.2.0.32/src/or/eventdns.c  2008-02-26 11:56:28.000000000 -0800
+++ tor-0.2.0.32-agl/src/or/eventdns.c 2008-12-28 12:18:22.000000000 -0800
@@ -121,6 +121,7 @@
 #endif

 /* for debugging possible memory leaks. */
+#include "src/common/util.h"
 #define malloc(x) tor_malloc(x)
 #define realloc(x,y) tor_realloc((x),(y))
 #define free(x) tor_free(x)
Only in tor-0.2.0.32-agl/src/or: Makefile
diff -ur tor-0.2.0.32/src/or/or.h tor-0.2.0.32-agl/src/or/or.h
--- tor-0.2.0.32/src/or/or.h  2008-11-20 14:14:26.000000000 -0800
+++ tor-0.2.0.32-agl/src/or/or.h 2008-12-28 12:03:48.000000000 -0800
@@ -75,7 +75,7 @@

 #include "crypto.h"
 #include "tortls.h"
-#include "log.h"
+#include "src/common/log.h"
 #include "compat.h"
 #include "container.h"
 #include "util.h"

12) Finish up

I didn't bother building any of the Tor utilities once I had the Tor
binary. You can copy it to the phone with adb push again and run it
via the shell.

First you should `export HOME=/sdcard` because the tmpfs is very small.



That gets Tor running, however it's hardly very neat.

The rest of Android is designed around Activies, as documented in the
SDK documentation. I suspect that the way to go would be to build Tor
as a .so, renaming the main function. You can use JNI[1] from a Java
thread to start running Tor by calling the new alternative main. If
you do this, you'll want to read [2] otherwise the system will
randomly kill the process.

I believe that there's a way to get Android to use an HTTP proxy.
Certainly there's an http_proxy field in
frameworks/base/core/java/android/provider/Settings.java. You might
find details online about poking a value in a SQLite table. The
sqlite3 binary that they reference isn't shipped on the phones, but
you find it in mydroid/out/target/product/generic/system/xbin.
However, I don't believe that the sqlite file lives in the same place
anymore and I don't know where it moved to.



AGL

[1] http://davanum.wordpress.com/2007/12/09/android-invoke-jni-based-methods-bridging-cc-and-java/
[2] http://code.google.com/android/reference/android/app/Service.html

-- 
Adam Langley agl@xxxxxxxxxxxxxxxxxx http://www.imperialviolet.org