December 6, 2014.

The idea is to make a proper ssh implementation for Android.  Important
features:

   * it should run happily without root (on a non-root port)

   * it should be a regular android app requiring no special permissions,
     and not requiring any 'magic' executable files

   * should not rely on busybox

   * preferably support sftp

   * open source

The existing apps are either expensive, don't work, need root, or too
complicated, or a mix of all of the above.  And none of them are open
source.

I figure I'll start with dropbear, which I will run through JNI instead
of putting it in its own binary (because making such a binary executable
is a bit of a hack).

So that's the plan........


December 14, 2014.

I got dropbear to compile under the Android NDK, so now it's time to work
on the Android side of it.

I need:
  * a Service that can be started, stopped, and queried for whether it's
    running or not
  * a Thread to implement the Service's work (by calling into dropbear's
    main()), which can also be stopped.
  * a config UI with at least these choices:
    - bool: start on boot (def: false)
    - number: port number (def: 2222)
    - string: path to authorized_keys file (def: /sdcard/ssh)
    - string: name of default shell (def: /system/bin/sh -l)
    - string: default path for HOME (def: /sdcard/ssh)
    - button: start or (if it's running) stop


December 15, 2014.

Getting to the fun part.  Process management...

To start sshd, it seems like I can startService().  Then in the Service's
onStartCommand(), call startForeground() so it won't be killed (return
START_STICKY too?).

The question is if dropbear's main() should run under a separate Thread,
or a separate Process.  The trouble with a Thread is that it might be
hard to kill.  The trouble with a process is that there is no way to
report back status (such as a failure to start sshd).

Connectbot starts a new process for its shell -- it really doesn't have a
choice because the shell binary isn't linked with Connectbot, and exec()
in a thread stinks.  To stop it, it just closes stdin/stdout!!!  So
zombies can (and do) linger.

I suppose dropbear could be in its own process if it had something like
stdin/stdout to communicate failure?  Or it could just write error
messages to (i.e.) /sdcard/ssh/log.  To stop the service, it would just
use kill().

I am curious how the main waiting-for-connections loop looks, but even if
it uses select(), I'm not sure how I would honor Thread.interrupt() or
whatever.  It's not guaranteed to interrupt select(), and I'm not keen on
adding an arbitrary timeout/polling feature to it.

XXX - use ptmx
XXX - service for start (startForeground, fork) and stop (kill, stopService)
XXX - logging facility instead of stdout/stderr
XXX - disable utmp/wtmp

                final int shellPid = pids[0];
                Runnable exitWatcher = new Runnable() {
                        public void run() {
                                Exec.waitFor(shellPid);
                                bridge.dispatchDisconnect(false);
                        }
                };
                Thread exitWatcherThread = new Thread(exitWatcher);
                exitWatcherThread.setName("LocalExitWatcher");
                exitWatcherThread.setDaemon(true);
                exitWatcherThread.start();

XXX - scp
XXX - zlib
XXX - rsync