Monday, October 24, 2011

Android Command Line Dev with VI

Notes on developing Android apps from *NIX command line.

If you are a Vi user, then building your Android application from the command line can save you time.  Here are my notes on setting up Vim w/ tags and code completion for Android development.  I've also included the relevant Ant commands for building Android apps from the command line.  The example includes the commands for building and installing an Android app that links to a dependent java library which resides outside of the project source tree (in this case, the lvl lib), along with a C shared library that resides in the local jni/ directory.

Useful Vim Plugins for Android Development
Setting up Vim JDE (vjde) requires a few configuration changes in order to work well with Android projects.  First, you will need to download vjde.tgz version 2.6.18 from http://www.vim.org/scripts/download_script.phpsrc_id=16253

Place vjde.tgz in $HOME/.vim and tar -zxvf vjde.tgz from within $HOME/.vim.  Change the permissions on $HOME/.vim/plugin/vjde/readtags as follows:
$ chmod +x $HOME/.vim/plugin/vjde/readtags
Fire up an empty editor:  $ vim and enter the following in command mode:
:helptags $HOME/.vim/doc
:h vjde 
will then pull up the help page.

That should take care of setting up vjde.  Now cd to your Android project dir.  Open a blank editor and input the following in command mode:
:Vjdeas .myproject.prj
:let g:vjde_lib_path='/<path_to_android_sdk_top_level_dir>/platforms/ \
<desired_sdk_target>/android.jar:bin/classes:build.classes'
:Vjdesave
:q!
Next, Open up a source file in your project and type :Vjdeload .myproject.prj in command mode (or script and/or add to .vimrc).  You can then use <ctrl-x><ctrl-u> for code completion. For example: import android.<ctrl-x><ctrl-u> and you will get a nice little dialog box for browsing the matching frameworks.

Next, run ctags over your java and native sources as follows:
$ ctags -R src gen jni
Once NERD tree and Taglist are placed in ~/.vim/plugin/, the following lines in your .vimrc will allow you to use <ctrl-n> and <ctrl-m> to toggle the file explorer and visual tag list.
nmap <silent> <c-n> :NERDTreeToggle<CR>
nnoremap <silent> <c-m> :TlistToggle<CR>
Also, if you need a status line:
set statusline=\ %{HasPaste()}%F%m%r%h\ %w\ \ CWD:\ %r%{CurDir()}%h\ \ \ Line:\ %l/%L:%c
function! CurDir()
let curdir = substitute(getcwd(), '/Users/myhomedir/', "~/", "g")
return curdir
endfunction

function! HasPaste()
if &paste
return 'PASTE MODE  '
else
return "
endif
endfunction
Vim should be good to go at this point. cd back to $HOME/src/myproject.  This particular example accounts for a dependent Java library (the lvl) that resides outside of the project source tree, a shared library (which consists of a few C files natively compiled), and plain java source files in the appropriate src/com/ package subdir.

From within your top level project dir (assuming that you came from Eclipse, otherwise, you can use android create ...),
$ android update project --name myproject --target <desired_sdk_target> \
  --path $HOME/src/myproject
$ android update project --target <desired_sdk_target> --path $HOME/src/myproject \
  --library ../lvl_lib_dir
Make sure to check project.properties to ensure that the android.library.reference.1 variable now contains the relative pathname of the lvl lib directory.

Assuming that jni/Android.mk and jni/Application.mk are appropriately setup for your shared library, run ndk-build from the top level project directory.
ant debug should now handle the build and debug version of the application package file.

Start up an Emulator and then install your app with a
db -r install bin/myproject-debug.apk or use ant install.
Next, open the Dev tools application in the emulator and configure the following: set wait for debugger and select your application for debugging.

Next, run ddms & and check the debug port. It should be 8700.
Subsequently, start your activity with
adb shell 'am start -n com.mycohname.myproject/.BaseActivityName'
And finally, connect via jdb from the shell with
$ jdb -sourcepath $HOME/src/myproject -attach localhost:8700 
and start your debugging.

Tuesday, August 16, 2011

OpenSSH Security - Client Configuration


OpenSSH provides a suite of tools for encrypting traffic between endpoints, port forwarding, IP tunneling, and authentication. The below instructions outline a client side OpenSSH configuration where the client is running on OS X. The built in firewall, ipfw, is enabled on the client to restrict outbound and inbound traffic. Part II (currently on hold) of this guide will cover the configuration of OpenSSH on the server along with the available options and alternatives for authentication, authorization, and traffic encryption. The configuration will force AES 256 in Counter Mode and will restrict the available Message Authentication Algorithms that may be used between endpoints. Most of the options in the ssh configuration file on the server will be disabled, public key authentication will be used, password authentication will be disabled, and the ssh daemon will bind to a high number port. Multiple SSH sessions will use the same connection via the ControlMaster and ControlPath client configuration directive. Also, a server certificate will be generated and used to sign user public keys. The CA signed user public keys constitute a user certificate which the server will in turn use for client authentication. PF will be used on the server for stateful packet filtering, connection blocking, and connection throttling. The below configuration will also detail

First and foremost, the client has ipfw enabled and the firewall ruleset is configured in /etc/ipfw.conf. ipfw has been configured to block all inbound traffic and block all outbound traffic except for the ports and IP addresses that are necessary for connecting to the OpenSSH server. The server is running FreeBSD 8.2.

FreeBSD 8.2 - sshd on a.b.c.d:21465 pf |  <--------Internet---------->  | ipfw  OS X Lion - ssh client
To start with, you will need to install coreutils and apg on the client. coreutils and apg can be obtained from Mac ports and can be installed as follows:

client: $ sudo port install coreutils 
client: $ sudo port install apg 

Before generating your public/private keypair, You will need to generate a strong passphrase for your private key. It is important to store this passphrase in a secure location, not on your computer.

client: $ openssl rand -base64 1000 | shasum-5.12 -a 512 | apg -M SNCL -a 1 -m 20 -x 20

Depending on your version of OpenSSH (should be using latest stable for your OS), ECDSA may be used in addition to DSA and RSA. Certificates may also be used for user and host authentication. See the ssh-keygen man page for details.
You can generate your keypair using the following command. When prompted for the passphrase, use the output from the above command.

client: $ ssh-keygen -b 4096 -t rsa -C"$(id -un)@$hostname)-$(gdate --rfc-3339=date)"

Here is an example of how to use ssh-keygen to generate a public/private keypair using the Eliptic Curve Digital Signature Algorithm. Both the client and server must be running a version of OpenSSH >= 5.7.

client: $ ssh-keygen -b 521 -t ecdsa -C"$(id -un)@$hostname)-$(gdate --rfc-3339=date)"

Now, we need to push the public key to the server and place it in the authorized_keys file of the user that we are going to log in as over ssh.
The ssh-copy-id command can be used to automate this process. On the OS X client, the ssh-copy-id command does not come preinstalled with SSH. The ssh-copy-id command can be obtained from http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/ports/security/ssh-copy-id/files/ssh-copy-id?rev=1.1;content-type=text%2Fplain. After downloading the script, change its permissions and place it in your path.
At this point, you should already have a server that is running OpenSSH on port 22 with the default configuration. Thus, you can transfer your public key with the following command:

client: $ ssh-copy-id -i ~/.ssh/id_xxxyy.pub bryan@a.b.c.d \

It is time to setup connection sharing. Create the following file if it does not currently exist.

client: $ ls -l ~/.ssh/config -rw------- 1 bryan scclp 104 Aug 13 10:55 config

The file should contain these lines.

ServerAliveInterval 60 Host a.b.c.d ControlMaster auto ControlPath ~/.ssh/sockets/%r@%h:%p

The goal is to only allow connections to the server in AES 256 Counter mode, with umac-64 or hmac-ripemd160 MACs, and compression, on a non-standard SSH port from a designated IP range using public key authentication. Connections will also be throttled and SSHGuard along with a few custom PF rules on the server will be used to block and log attackers. The commands that the client will use to connect to the server will look like this:client: 

$ alias sshconnect="ssh -l bryan a.b.c.d -p 21465 -C -c aes256-ctr -m umac-64@openssh.com,hmac-ripemd160 client: 
$ alias sshtunnel="ssh -v -ND 8090 bryan@a.b.c.d -p 21465 -C -c aes256-ctr -m umac-64@openssh.com,hmac-ripemd160 client:
$ alias sshmonitor="yes | pv | ssh -l bryan a.b.c.d -p 21465 -C -c aes256-ctr -m umac-64@openssh.com,hmac-ripemd160 \"cat > /dev/null\"" client: 
$ alias sshportforward="ssh -f bryan@a.b.c.d -p 21465 -C -c aes256-ctr -m umac-64@openssh.com,hmac-ripemd160 -L 15478:localhost:15479 -N" client: 
$ alias sshportforward2="ssh -f bryan@a.b.c.d -p 21465 -C -c aes256-ctr -m umac-64@openssh.com,hmac-ripemd160 -L 17293:localhost:17294 -N"

Alternatively, Ciphers, MACs, and compression can be specified in the user config file as follows:

ServerAliveInterval 60 
Host host.name.com 
    ControlMaster auto 
    ControlPath ~/.ssh/sockets/%r@%h:%p 
    Port 21465 
    User bryan 
    Ciphers aes256-ctr 
    Compression yes 
    MACs umac-64@openssh.com,hmac-ripemd160 
    StrictHostKeyChecking yes


User and Host certificates provide a more convenient method of authentication for multiple clients (users) and servers (hosts). Certificate revocation can also provide an easier method of quickly invalidating user access.A certificate authority key pair is first generated as follows. The ca is then placed in the /etc/ssh directory on the host.

ca $ ssh-keygen -t ecdsa -b 521 -f user_ca server $ sudo mv user_ca* /etc/ssh/

On the client, generate a public/private key pair and then copy the public key to the server so that it can be signed with the ca. Make sure to set the validity period of the certificate. Alternatively, a host key may be signed with a ca key that is stored in a PKCS11 token. OpenSSH supports ca keys stored PCKS11 tokens. Check your version of SSH and see ssh-keygen for more information.client 

client $ ssh-keygen -t ends -b 521 -f ~/.ssh/id_ecdsa 
client $ scp .ssh/id_ecdsa.pub bryan@server-ca:~/user_public_keys 
server-ca $ ssh-keygen -s /etc/ssh/user_ca \ 
      -O source-address=clientip 
      -O permit-pty 
      -O no-port-forwarding       
      -O no-user-rc 
      -O no-x11-forwarding \ -V -1d:+52w1d -z 6739301351 -I "bryan"       -n bryan,clienthostname id_ecdsa.pub
id "bryan" serial 6739301351 for bryan,clienthostname valid from 2011-08-18T15:05:24 to 2012-08-17T15:05:24 

Copy the signed user cert back to the client.

client $ scp bryan@server:~/user_public_keys/id_ecdsa-cert.pub ~/.ssh/ 

Setup TrustedUserCAKeys and AuthorizedPrincipalsFile files. Subsequently, set appropriate options in /etc/ssh/sshd_config on the server.

server-ca $ sudo cat /etc/ssh/user_ca.pub > /etc/ssh/trusted_user_ca_keys 

Modify /etc/ssh/authorized_principals to include the following lines.bryan from="clientip" bryan
Modify /etc/ssh/sshd_config on the server to include the following lines

TrustedUserCAKeys /etc/ssh/trusted_user_ca_keys 
AuthorizedPrincipalsFile /etc/ssh/authorized_principals 

Now, restart sshd on the server and add an appropriate host configuration for certificate authentication to ~/.ssh/config on the client.

Last of all, if you want to setup a host certificate, you will need to use the -h option with ssh-keygen when signing a host key.

It is important to always keep OpenSSH updated with the latest, stable version that has been released for your operating system.

Resources

OpenSSH, http://openssh.org

fwknop, http://cipherdyne.org/fwknop/

OpenBSD, http://openbsd.org

FreeBSD, http://freebsd.org

Sunday, February 27, 2011

Cross compiling BusyBox for the Nvidia Tegra 2

The Motorola Xoom tablet is powered by an Nvidia Tegra 2, Dual-Core ARM Cortex A9 processor and runs Android 3.0, Honeycomb. There are no third party UI replacements or additions.

The below instructions are for cross compiling a statically linked BusyBox binary for an Nvidia Tegra 2 tablet.

linux host ~$ wget http://busybox.net/downloads/busybox-1.18.3.tar.bz2
linux host ~$ wget http://www.busybox.net/downloads/busybox-1.18.3.tar.bz2.sign
linux host ~$ http://busybox.net/~vda/vda_pubkey.gpg
linux host ~$ gpg --check-sigs vda.linux
linux host ~$ gpg --verify busybox-1.18.3.tar.bz2.sign
linux host ~$ sha1sum busybox-1.18.3.tar.bz2
linux host ~$ md5sum busybox-1.18.3.tar.bz2
linux host ~$ bzip2 -cd busybox-1.18.3.tar.bz2 | tar xf -
linux host ~$ cd busybox-1.18.3
linux host ~$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- defconfig
linux host ~$ make CFLAGS=--static LDFLAGS=--static ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
linux host ~$ adb remount
linux host ~$ adb push busybox /system/xbin/busybox
linux host ~$ adb shell chmod 0755 /system/xbin/busybox
linux host ~$ adb shell
linux host ~$ cd /system/xbin
linux host ~$ ./busybox --install -s /system/xbin
linux host ~$ cd /mnt/sdcard
linux host ~$ echo "export PATH="export PATH=/system/xbin:/sbin:/vendor/bin:/system/sbin:\
  /system/bin" > profile
linux host ~$ echo "ENV=/mnt/sdcard/profile /system/xbin/ash" > /system/bin/alsh
linux host ~$ chmod 0755 /system/bin/alsh
linux host ~$ alsh
linux host ~$ uname -ia
linux host ~$ Linux localhost 2.6.36.3-g2a65edc #1 SMP PREEMPT Mon Feb 7 15:24:33 PST 2011
  armv7l GNU/Linux