On Sun, Dec 28, 2008 at 3:55 PM, Adam Langley
<agl@xxxxxxxxxxxxxxxxxx> wrote:
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