ERROR HANDLING

Consider return values from handlers. A return value has several
components:

 x Success/failure indication
 
 x Next action (continue, close immediately, flush buffers then close,
   exit...)
 
 x Process return value in case the proper action is to exit.

It should be possible to encode all this information into a simple
integer. And some actions are orthogonal. For instance, a handler may
fork, and send a few messages. Now, both the fork action and any error
codes from writing must be taken care of.

Perhaps errors when processing data on one socket should propagate to
another one?

Can one safely assume that the only error that can occur when sending
a packet (typically by A_WRITE(connection->write, packet)) is LSH_FAIL
| LSH_CLOSE?


KEYS

Code is needed to generate, store and read dss keys. Preferably in a
SPKI/s-expression form.

Fix compliance with the (next) SPKI draft. In particular, the order of
fields and the encoding of numbers needs updating.


S-EXPRESSIONS

Add newlines and pretty printing to the sexp formatter.


USERS

Functions to lookup users, their passwords and .lsh/authorized_keys.


CHARSETS

User names and passwords must be translated from the systems charset
(default iso-8859-1) to UTF8.


CONFIGURATION

Read configuration files. Better command line options. 

LOGGING

Use syslog to log server startup, shutdown, and user authentication.
Update utmp (users currently logged in), wtmp (record of logins) and lastlog
(last login time).
Use tcpwrapper's libwrap to log connections and perform access control.


ALLOCATION

Not all packet consumers free processed packets properly.

Use separate allocation function for objects that are subject to gc,
and those (for instance, strings and atom lists) which are deallocated
explicitly). 

Implement a mark&sweep gc.

Use separate "storage-types" for lsh_string_alloc and
lssh_space_alloc.

Make lists of integers (usually atoms) their own type. Can this be done
in such a way that they can also be allocated statically? 

Have the allocator initialize all objects automatically.

Better typechecking of non-heap objects. To do this one would also
need valid isa-pointers in classes (as classes are statically
allocated). If this is done properly, the meta feature could also be
cleaned up a little.

Fix gc_kill to deallocate objects immediately.

Consider adding reference counts to strings.


CHANNELS

Create some generic methods for connecting a channel to one or more
files. The data shuffling and error handling should be very similar
for most channel types.

Consider which errors can occur in the channel callback functions;
they are probably somewhat different from errors in higher levels. For
instance, a writing to a file associated with a channel may fail. In
that case, the channel should be closed, but the connection should not
die. Handle the LSH_CHANNEL_FINISHED code properly.

Fix the flow control (it's broken on the receiving end).


CHANNEL CLOSE

Channels may need some live-ness status. For instance, a remote
process may close its stdout and stderr, but still keep on running. In
this case, the local process should close it's stdout and stderr, but
not close the channel until it has received a close message and
possibly an exit status.


USER INFO

Where should the user information (name, home directory, login shell,
etc), be stored? Is there any reasonable place but the connection
structure? Perhaps the channel_open handler for the session is a
reasonable place? Then we only have to figure out when to install that
information.


PROCESSES

Dying children must be handled. For example like this: Use a signal
handler to set a flag when a child dies. Let the backend loop (io.c)
look at this flag, wait() to get status from dying children. Use an
alist pid->callback to report children's exit status back to the remote
end. Another issue are process groups... Are they relevant? 

Kill child processes if its channel or its connection is closed
unexpectedly. 


FREENESS

It might be safer to remove patent-encumbered code like IDEA code from the
regular lsh distribution, and make it available separately (this approach is
taken with GnuPG).

scsh is not free software. Olin Shivers (one of the scsh copyright owners)
has indicated he is willing to free it, but currently he has no time to
handle the paperwork. We need scsh to be freed, or we need to rewrite the
Scheme scripts so that they are as portable between Scheme implementations
as possible, or switch to a free Scheme implementation, like Guile. This is
not urgent however.

CAST is probably not patent encumbered (Schneier doesn't mention patents);
check what RFC 2144 (CAST-128) says on this subject.


MISC

Try to find out why read() sometimes returns -1 and sets errno==EPIPE,
on sparc-linux, 2.0.33, redhat-5.1, glibc.
Note: Debian's sparc port uses glibc2.1, rather than 2.0; maybe Red Hat does
too? Quite a lot of things have changed between 2.0 and 2.1; this might well
be a documented feature of 2.1.

"lsh" is already used as the name of a shell (included in Debian;
Description: Baby Shell for Novices with DOS compatible commands). Perhaps
we need to change our name?

Get a decent source of random (the current version will fall back to a
really poorly seeded generator if /dev/urandom is not available); most
likely, reusing the rand* from GPG's g10 is the best option. Werner
Koch is now working on making a libgcrypt out of GPG's random and
crypto code.

Use UNUSED where parameters are unused intentionally.

Fix shadow passwd support.

Make it cleaner wrt. more gcc warnings.

Handling of user authentication failures seems broken.

Fix desTest.c to use proper declarations of its function pointers, and
have autoconf check for rusage().

Use argp instead of getopt_long (but we must first find out how to use
argp on non-glibc systems).

Have autoconf check for vsnprintf, and include an implementation for
systems that don't have it. Hmm. Perhaps we should use a custom
vprintf-like function anyway, so that we can write to our own streams,
not just to FILE * and fix buffers.

It seems that it is a little difficult to detect that an asyncronous
connect() failed; poll() indicates that both reading and writing is
possible, but write failes (with EPIPE/SIGPIPE) later. Perhaps a
linux-problem?

Extract handling of hex and base 64 encodings into a separate file.

Include length fields when hashing in
publickey_crypto.c:init_diffie_hellman_instance(). Perhaps some of
this code should be moved to keyexchange.c? Similar considerations
apply also to other hashes.

Fix so that lsh compiles in the absense of zlib.

Fix the cvs_headers not to use the construction "sed -f -", as that
doesn't work with Solaris sed.

It is a nice idea to generate a typedescr.h table to aid debugging.

Make separate object files for most generated files, instead if
#including them. Particularly important for digit_table.h, which is
used in several places.

Fix configure script to add appropriate -R options when linking.
Currently, using a shared libz.so doesn't work.
