view doc/design.txt @ 1000:0fbafade2d85 HEAD

If auth/login process died unexpectedly, the exit status or killing signal wasn't logged.
author Timo Sirainen <>
date Tue, 21 Jan 2003 09:58:49 +0200
parents 13f27425cb88
children 6e893f3f9837
line wrap: on
line source


Security is the major goal of this project, with reliability coming second.
I also try to keep things fast, extensible and portable.

Things are broken into multiple processes running with minimal required
privileges. Communication between processes is trusted as little as
possible. Processes running as root are kept as simple as possible even if
it means minor performance hits.


Runs as root. Executes new processes, some by itself and some by request of
another process. The requested processes can never be started as root, and
the allowed UID range can also be limited.

It's also possible to configure everything to be run under a single UID.
This is useful only if you wish to use imap somewhere you don't have root


Runs as non-privileged user (imapd). Handles accepting new client
connections and parsing commands until the client is authenticated. There
can be either a few of them which handle multiple connections, or one
process per connection. One per connection is much more secure in case it's
ever found to be exploitable, but it's also less efficient.

SSL and TLS connections are also fully handled by the login process.
Instead of passing the connection's fd to imap process, login creates a new
anonymous UNIX socket and uses it to translate communication between imap
process and the client. If you're using one login process per connection,
this also means that you have actually two processes all the time for an
active SSL IMAP connection.

Since SSL protocol is quite complex and I'm using gnutls which is still in
beta, it shouldn't be trusted to be fully secure. Using one login process 
per connection should however make it quite safe to use, as the login is
running in a chrooted environment without any privileges. However, the
attacker could get your private SSL key..

Note that if you let a single login process handle multiple connections, a
security flaw would allow the attacker to see all the other user
connections connecting to it, possibly hijacking them or stealing their
passwords if plaintext authentication was used.


Runs under minimal required privileges to be able to authenticate users.
In case of shadow passwords or PAM, that's root. Communicates with
imap-login and imap-master to authenticate users.

 * imap-login
    - Receives LOGIN or AUTHENTICATE command
    - Begins authentication with imap-auth process, with AUTHENTICATE
      continuing passing data between client and imap-auth until done
       - If successful, we've received a cookie which we send to imap-master
          * imap-master
	     - Requests data from imap-auth for the cookie. Data includes
	       UID, GID and mail format and mail format specific data (eg.
	       mail directory). Optionally also receives chroot directory.
	     - Checks that the UID is in valid range, and that it's allowed
	       to be chrooted under given directory
		- If everything is valid, pass the connection to imap process
	     - Replies to imap-login whether everything was valid
	  - If successful, stop processing the connection, imap process takes
	    care of the rest

 * imap-auth
    a) Receives authentication request with given protocol
        - Initialize the request in protocol-specific manner
	- If failed, send a failure-reply to client
	- Otherwise send a cookie to client
    b) Receives continued authentication request for given cookie
        - Verifies that the cookie is valid, replying if not
        - Handle the data in protocol-specific manner
	- Reply to client with information whether the authentication
	  is finished
	- Reset cookie expiration time
    c) Receives a request to receive data associated to cookie
        - Verifies that the cookie is valid, replying if not
	- Reply with the data

Cookies are associated to a specific imap-login process, so one process
cannot steal another one's authentication request by pretending to be it.


Runs non-privileged and optionally chrooted (when it's safe). Since this is
the largest part of the imapd, this is where most of the potential security
flaws are.

Maildir and mbox formats use a few index files to look up data fast, the
actual mail files aren't opened unless they're really needed. The index
files are accessed using shared memory maps and locked using fcntl().

Using memory maps creates a security problem if the file isn't trusted. It
might well be possible to create a buffer overflow in some function by
modifying the file as while it's being used. Currently this should not be a
problem as we require write access to the files ourself, so attacker
shouldn't be able to get any extra privileges by exploiting the imap

Other than the memory mapping problem, index files are not trusted to
contain valid data. Everything in them is validated before being used.

Supporting shared mailboxes will be a small problem. We probably shouldn't
even try to support using non-trusted index files but rather create trusted
indexes separately for each user. If however the users don't have direct
access to the indexes files, they could optionally be shared.


Indexer may be started by master process when it thinks there's some extra
time to be used. It goes through users' mailboxes and compresses or
rebuilds indexes when it sees a need for it. The actual indexing is done by
dropping root privileges just as with imap process.