>From time to time during the last couple of months, I've been
reorganizing the lsh code. At the moment, I've got far enough to be
confident that it will work well, even though there still are several
important pieces missing. The most important change is a split into
several processes. On the server side, responsibility is split into
three programs, with cuts between the layers in the ssh protocol:
* lshd: Accepts new connections, speaks the ssh transport protocol
(i.e. key exchange, encryptioon, authentication, compression),
authenticates the server. Userauth and channel related messages
(i.e. ssh packets with first byte >= 50) are not processed, just
past on via a pipe to a "service" process. Normally runs as root.
* lshd-userauth: Implements the ssh userauth protocol, and is
started by lshd when the client requests the "ssh-userauth"
service. Usually started as root, and changes uid to that of the
logged in user before it exec:s the next program.
* lshd-connection: Implements the ssh connection protocol, with
multiple channels, forwardings, etc. Always runs as the logged in user.
The idea is to make the components that need root privileges smaller
and simpler. lshd-transport doesn't need to know anything of the more
commplex parts of the ssh protocol. Since lshd-userauth runs as a
separate process, it can use ordinary blocking i/o, and it can freely
use blocking api:s to talk to other systems, e.g., kerberos and pam.
On the client side, I also split functionality into two programs,
although this is of less importance:
* lsh-transport: Implements the client side of the transport and
userauth protocols.
* lsh: Implements the connection protocol, channels, forwardings
etc. Should also take over the gateway/connection sharing
functionality. lshg should no longer be a separate program.
A side effect of this split is that I hope it should make it easier
for people to reuse the ssh transport protocol for other applications.
It should be reasonably straight forward to write glue to make an
arbitrary network service fit as an ssh "service", with or without ssh
userauthentication. The current transport protocol implementation is
also much closer to being an "ssh library" than the old code was.
A related change is that the fairly complex i/o abstractions used by
lsh have been ripped out. The parts that still need non-blocking i/o,
i.e. everything but lshd-userauth, now use the liboop library
directly to install the appropriate i/o callbacks.
At the moment, basic session channels and port forwarding works.
Missing pieces:
* Since the server functionality is split in several processes, it's
no longer practical to have all configuration via command line
options. Configuration files are necessary. This is not yet
implemented. The plan is to have one file per program, stored
under /etc/lsh. All features should be off by default, but each
program should have a command line option that exports a
reasonable and commented sample file.
* utmp/wtmp logging. This actually the only issue I found so far
that's fundamentally difficult to get right. The problem is that
the logging is tightly coupled to pty allocation. And the pty
allocation is done by lshd-connection, which doesn't have
sufficient privileges to manipulate the system log files. I don't
know how to best solve this, it seems like some daemon or setuid
program is needed that can be made responsible for both pty
allocation and proper logging.
* gateway/connection sharing functionality. Not yet implemented, but
it should be fairly straight-forward.
* assorted missing features, like x11 forwarding and pty allocation.
Also no big deal, but it's not currently working.
* in some places, the code relies on modern unix features, such as
getaddrinfo. Work is needed to make the code portable to a wider
variety of systems.
If anybody is curious, check out the branch
"experimental_BRANCH_20050201" from CVS.
Happy hacking,
/Niels