Hacking the Touchpad, Part 1

I just picked up a discounted HP TouchPad from my man Greg Chan (via a real stand-up guy who would probably prefer to remain anonymous).   Haven’t even played around with WebOS; it doesn’t interest me in the slightest.  We need to get Android on this contraption!  Here are my modest contributions to the effort. First: an attempt to get an SSH client and server running.

Preparing for the Worst

First, establish a backup plan!  Once you register the device, you’ll have access to the HP WebOS site.  From there you can download WebOS Doctor, a Java app that will let you restore your TouchPad should something untoward happen to it.

I haven’t used WebOS Doctor yet and I hope I never have to.  But as a backup-backup plan, let’s make a copy of the filesystem.  Follow the instructions here to get terminal (root) access to the TouchPad. After logging in, I ran this command:

tar cvfz /media/internal/downloads/backup.tar.gz / --exclude '/media/internal/downloads/*

to backup the filesystem.  It’s far from a perfect backup, and it may never be useful, but I like having it around just in case.  Let me know if you need a copy, it’s about 300MB.

Setting up a Cross-Compiler

Wow, setting up a cross compiler has gotten a lot easier since the last time I checked.  All I had to do was download the ARM cross-compiler from here and install it.

The cross-compiler build tools are set up with weird names like “arm-none-linux-gnueabi-ar”.  There’s got to be an easier way to configure this but I just ran this command to set up shortened symlinks:

rweeks@faithless:/bitsafe/CodeSourcery/Sourcery_G++_Lite/bin$ for CMD in *; do CMD_TRIM=`echo $CMD | sed -e 's/arm-none-linux-gnueabi-//'`; ln -s $CMD $CMD_TRIM; done

Then you can control whether you’re using your native buildtools or the cross-compiler buildtools just by setting your $PATH.

Building OpenSSH

I figure a good first-day milestone is to get OpenSSH running on the TouchPad.  I’ll try to work my way up to a full-on Android distro :).  I pretty much followed the instructions here with some minor changes for the cross-compiler.

First I defined a directory where I want to put all the build output:

mkdir /bitsafe/arm-openssh-server/output

The commands I used to build zLib:

./configure --prefix=/bitsafe/arm-openssh-server/output
make && make install

The commands I used to build openSSL (this will take a while):

./Configure --prefix=/bitsafe/arm-openssh-server/output linux-armv4
make && make install

The commands I used to build openSSH:

./configure --host=arm-none-linux-gnueabi --prefix=/bitsafe/arm-openssh-server/output --with-zlib=$PWD/../zlib-1.2.5 --with-ssl-dir=../openssl-1.0.0d
make && make install

The OpenSSH build will fail to install due to the cross-compiler (it can’t strip the output files).  But that should be OK.

Deploying OpenSSH to the TouchPad

OK, everything should be built at this point.  You can double-check that you’re using the cross-compiler by, eg.

find . -type f -print0 | xargs -0 file

Where you see executable files, it should indicate that they have been built for the ARM architecture.  I wrapped up everything in a tarball:

tar cvfz openssh-server.tar.gz arm-openssh-server/

This grabbed my “output” directory, as well as the source directories for zLib, openSSL and openSSH (in case any files failed to install correctly into output/)

I had a vastly complicated procedure in mind to copy the tarball to my TouchPad, but it turns out that the TouchPad just mounts as a vfat file system which was mounted automatically by my build machine.  The whole thing was just a drag-and-drop, which was nice.

Extract the tar file like so:

tar xvfz openssh-server.tar.gz --no-same-owner

You’ll get a bunch of errors on the extraction because it can’t create symbolic links: I think this is because you’re extracting to a filesystem that doesn’t support symlinks.  No big deal.

Test that the cross-compiler worked!

cd /media/internal/downloads/arm-openssh-server/zlib-1.2.5
zlib version 1.2.5 = 0x1250, compile flags = 0x55
uncompress(): hello, hello!
gzread(): hello, hello!
gzgets() after gzseek:  hello!
inflate(): hello, hello!
large_inflate(): OK
after inflateSync(): hello, hello!
inflate with dictionary: hello, hello!

Starting OpenSSH Server

Harder than it sounds!  The root filesystem is mounted read-only by default, but you can hack your way around that with:

mount -w -o remount /

Then, add the sshd user and group to /etc/passwd and /etc/group

Setup an ssh key using ssh-keygen and set the “HostKey” property in sshd_config to point to the private key.

If you didn’t remount the root FS as read-write, you need to set UsePrivilegeSeparation to true.

Start sshd like so:

root@RussHPTouchPad:/media/internal/downloads/arm-openssh-server/openssh-5.8p2# $PWD/sshd -f sshd_config -ddd

(This is required because by setting up the “prefix” properties during the SSH build, all the commands will now be looking for their config in /bitsafe/…)

Last thing is to undo all the custom iptables config:

iptables -F
iptables -P INPUT ACCEPT
iptables -X ICMPFLOOD

OpenSSH 5.8 Running on TouchPad:

backfire:bin rweeks$ ssh -p 2222 root@
The authenticity of host '[]:2222 ([]:2222)' can't be established.
RSA key fingerprint is de:c2:1f:6a:30:e9:33:cc:85:f6:28:07:62:f9:8b:9b.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[]:2222' (RSA) to the list of known hosts.
root@'s password:
lastlog_openseek: Couldn't stat /var/log/lastlog: No such file or directory
lastlog_openseek: Couldn't stat /var/log/lastlog: No such file or directory
debug1: permanently_set_uid: 0/0
  SSH_CLIENT= 52206 2222
  SSH_CONNECTION= 52206 2222