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 - disable utmp/wtmp XXX - disable /etc/passwd (accept all usernames the same, and use the explicitly-provided shell and home directories) XXX - visit XXX in jni/interface.c XXX - allow user to specify parameters for dropbear XXX - convert UI to use proper preferences templates, and have ...->settings instead of putting it on the home screen XXX - scp XXX - zlib XXX - rsync