This implementation of POP3 daemon works with qmail-stype Maildirs, typically in user's home directories. It is very small and simple but have all required for pop3 daemon features.
mdpop3d can be used in two modes: it can work with mail storage only, providing only transaction stage of POP3 protocol, and it optionally can provide simple authentication. In this way it differ from e.g. qmail-pop3d, as by default this mdpop3d will work for most situatuons without additional support programs. For many sites with regular users this is sufficient.
mdpop3d can authenticate users using PAM or using plain unix getpwnam(3) and getspnam(3) methods, depending on compilation options. For PAM, service name used is pop3 and may be changed by -p option.
If PAM support is enabled, mdpop3d can be compiled with support of APOP command (note that this command is available only with PAM, and only if specially compiled in and if activated in command line). APOP implementation requires special PAM module capable of checking client-provided md5 hash against user's password. mdpop3d simply passes md5hash from client and server-generated timestamp to PAM library in place of a password (see USAGE section below), and some PAM module should be able to use this information to check client-supplied credentials.
When mdpop3d authenticates user itself (the default), it will by default look to Maildir subdirectory in user's home directory as returned by getpwent(3) call (usually this info stored in /etc/passwd file). This default directory name may be changed by -m option or by MAILDIR environment variable.
mdpop3d accepts the following command-line options:
mdpop3d may use some environment variables. Since this program should be invoked in some "friendly" environment (i.e. inetd(8) or some other daemon), and because environment used for non-critical tasks (mostly logging), usage of environment variables is safe.
Typically mdpop3d will be invoked directly by inetd(8) daemon, like this: pop3 stream tcp nowait root /usr/sbin/in.mdpop3d mdpop3d This is all that needed for usual functionality to serve regular unix users's mails. Also, mdpop3d may be invoked by some authenticator program, with correct userid, correct current directory and providing -a option. If you're familiar with qmail, than the qmail-popup(8) program is the best reference for this.
mdpop3d will always serve only one request, it is not a long-running process. Then client issues QUIT command, or when there is timeout or client disconnect condition, or if mdpop3d failed to authenticate user, it will terminate session and exit.
If APOP support was compiled in (requires also PAM support) and enabled in command line (with -A option), mdpop3d will accept and handle APOP command. This is alternative of using USER and PASS command that avoids transmission of passwords in cleartext over network, but also requires that cleartext password to be known by server. In order to use/enable APOP command, one should provide some PAM module that will have access to original client's password and can compute md5 hash from it and a timestamp string supplied by mdpop3d and compare computed value with client-supplied md5 hash. After receiving APOP command, mdpop3d will check if it is syntactically correct (by ensuring that supplied md5 hash value consists of exactly 32 lowercase hexadecimal digits), and will call pam library providing the string "APOP", space, this md5 hash as received from client, space and server-generated timestamp string, all in place of a password. For example, "password" provided to PAM may look like this: APOP 0123456789abcdef0123456789abcdef <12.3456@host> PAM module can check if password have this form ("APOP " prefix should be sufficient) and handle it accordingly. Example PAM config entry that support both APOP and USER/PASS: auth sufficient pam_apop.so auth required pam_unix.so ... In this case, pam_apop module should check if password starts with "APOP ", then obtain original password, compute md5 hash from timestamp string and this password and compare with supplied hash, and then return either success or failure. If it doesn't starts with "APOP ", then this module should return PAM_IGNORE, so that request will be processed by pam_unix module.
Note that such hypotetic pam_apop module is very site-dependant and not provided with mdpop3d. I would be glad to hear if anyone ever use the APOP feature at all...
If mdpop3d compiled with PAM support, it is trivial to support "virtual" maildirs using only one system account. For this, PAM module should be written that will check client-supplied credentials (username and password), and sets PAM_USER to the owner of virtual mail storage and $MAILDIR environment (either using pam_putenv() or setenv()) to point to maildir for a user relative to mail owner home. With this, mdpop3d can be used for both virtual mail storage and for regular user's maildirs simultaneously, having properly configured PAM module stacking. Please refer to PAM documentation for further details. To support many virtual domains, one can form POP3 username using both name of a user and domain name. Again, such a module does not provided with mdpop3d (yet), while it can be of general use.
mdpop3d supports the following POP3 commands:
When responding to client's commands, mdpop3d is somewhat quiet. For example almost all positive responces consists of just three characters +OK followed by CR, LF pair, no additional information used. POP3 used almost by software clients, not humans, and that additional info will always be discarded.
When using own implementation of password checking (via getpwnam(3) et al), password aging is not checked, and userid also (thus, mdpop3d will allow user with uid=0 and/or expired password to log in) -- only minimal checking done. This can be easily "cured" by using PAM that is far more preferable method anyway.
Any possible message from PAM discarded completely. This really isn't a bug in this daemon itself, but in difficulties communicating of non-interactive application uses predefined protocol with pam framework. On any error in pam mdpop3d responds with generic "login incorrect" message.
mdpop3d will not allow user to log in with empty password, and there is no way to tell it to do so. This may be considered a bug, but I mostly disagree.
POP protocol transmits plaintext passwords over network. For unsecure networks this may be not acceptable. As a workaround there may be some "autheticator" that sets up a secure (encrypted) connection and calls this mdpop3d program. One example of this is ssl wrapper such as stunnel(8).
mdpop3d reports incorrect message size(s). It uses message file size as returned by stat(2) system call as a message size, but this does not includes extra carriage return (CR) character at the end of each line, as required by POP3 protocol. It is a protocol violation, but I think that it isn't a (serious) issue. Many other pop3 daemons do the same.
mdpop3d will refuse to work with files in Maildir that have very long names and thus may overflow static mdpop3d buffer. Such a files will be silently ignored. Currently limit of filename is about 1018 characters, that should be sufficient for all environments where mdpop3d will run.
This software can be distributed under the terms of the GNU General Public License (GPL) version 2 or any further version.
This software and manual page has been written by Michael Tokarev, mjt@corpit.ru.