This file is intended to give others an overview about the code
structure of didentd to faciliate auditing and to communicate some of
my thoughts about the ident protocol in general.

All didentd* daemons are designed to run with a uscpi-tcp server. This
means you can run them with inetd and tcp-env or tcpserver. If you use
tcpserver with IPv6 functionality didentd will be able to answer
requests via IPv6.

didentd.c contains the main procedure which should be portable between
different operating systems. It reads information about the connection
from the enviroment like described at
http://cr.yp.to/ucspi-tcp/environment.html and
http://cr.yp.to/proto/ucspi-tcp.txt This way it also decides if the
client is calling via IPv4 or IPv6. didentd* reads the query from the
client into a 16 byte buffer using a 60 second timeout.

After changing the portnumbers read from the client from their ASCII
representation to binary representation it calles  
get_connection_info(4|6)(localip, localport, remoteip, remoteport);

This functions reside in different files and are operating system
specific. At the moment there is ony support for Linux /proc filesystem. 
The idea is that you just have to link an different file containing
get_connection_info() to support an other OS.

get_connection_info() on linux 1opens tcp (or tcp6) and scans the file
line for line comparing information with the Information about the
requested connection. This yields a problem described in the nmap
manpage documenting the "-I" option:

-I  This turns on TCP reverse ident scanning. As noted by Dave
    Goldsmith in a 1996 Bugtraq post, the ident protocol (rfc 1413)
    allows for the disclosure of the username that owns any process
    connected via TCP, even if that process didn't initiate the
    connection. So you can, for example, connect to the http port and
    then use identd to find out whether the server is running as
    root. This can only be done with a full TCP connection to the
    target port (i.e. the -sT scanning option). When -I is used, the
    remote host's identd is queried for each open port found.

The problem is that after a connection is established there is no way
of finding out which side initiated the connection. There are two
aproaches to solve this Problem.

a) disallow querys for ports below 1024.

b) disallow querys for connections to ports when there is another
   socket in TCP_LISTEN state for the same portnumber.

Solution b) has some overhead compared to a) but a has troubles with
outbound connections from low ports like used by ssh for example. 

At the Moment didentd* implements none of this since it was designed
to be compact and to hand out encrypted audit packets which would
defeat reverse ident scanning by delivering no information useful to
the attacker. didentd-name nevertheless would profit from a
implementation of this.

get_connection_info() returns the uid of the connection owner or
0xffffffff on an error condition / not found error.

32 bit unsigned int values are used for the uid to accomodate the
future switch to bigger uids in some Unices.

generate_answer() is called then to generate an answer string from
this Information. didentd-genanswer-crypt.c, didentd-genanswer-name.c
and didentd-genanswer-static.c contain different implementations of
generate_answer(). didentd-genanswer-crypt.c returns an encrypted
audit token, didentd-genanswer-name.c returns the username of the user
owning the connection and didentd-genanswer-static.c always retunrs an
answer with 'nope' as an username.

The Information gathered by generate_answer() is send back to the
client and logging to sttderr is done.

  --drt@un.bewaff.net - http://c0re.jp/c0rde/didentd/ 
