The porting of dovecot to netAuth consists of
(a) removing code,
(b) moving some code into the imap process and
(c) removing three of the four processes.
A dovecot process ported to
netAuth is not expected to perform the following functions:
message encryption using OpenSSL, GNU-TLS or the like;
user authentication;
performing the complex setuid() operation and
related code to ensure that the process does not have any
privileged left-overs (in the form of file descriptors) in the
unprivileged process.
Hence, code for these security sensitive operations need
not be implemented by the dovecot executable and can be removed.
Thus, summarizing the dovecot port to netAuth:
- the auth process (and its code) is eliminated
completely as the user authentication is performed by
the OS as part of connection establishment.
- from the master process, only
the code to bind to the privileged port and
to configure a new mail process with the
appropriate set of environment variables is retained.
(Dovecot passes configuration information to the imap process
as environment variables)
- from the login process, only the initialization of a new connection
(1a and 1b in Figure 6) is retained.
- the core functionality of
accessing and maintaining mailboxes in the imap process is retained.
Thus, the dovecot port to netAuth runs as a single process type
(following the design for a concurrent server
implementation shown in Figure 4).
The master, auth and login processes are eliminated
after taking a small amount code from them.
The resulting imap code
performs the following steps:
- initializes a socket to listen for new connections.
It performs a bind on the privileged port, a listen,
sets the accept mode to acceptByUser and
blocks on pre_accept
waiting for a connection from a user for which there is no imap process.
- when a connection from a new user arrives, the process
returns from pre_accept with the new user's information.
The process forks a child process to handle the user
and returns to waiting for a new user.
- the child process changes the user by executing
set_net_user with the user information from
the pre_accept call.
The child process runs as the new user.
This process can now accept the connections (for that user)
and process the MVA's requests.
The user is authenticated as part of the processing
in the network stack to accept a connection
Hence, pre_accept returns only for
authenticated users.
Connection requests of users that fail to
successfully authentication are dropped
(with a RST sent back).
Manigandan Radhakrishnan
2008-05-13