diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2001-08-19 13:05:58 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2001-08-19 13:05:58 +0000 |
commit | a6a38350f779ddf3a6febf67dda7714fe368e492 (patch) | |
tree | b8ffbc248c20776618b1d6aa93ec16abb19e78d1 /usr.sbin/popa3d/DESIGN | |
parent | 580e400b41d341c2ad1bfe153d5ca6553351703a (diff) |
libexec is the wrong place for popa3d, since it can be started WITHOUT inetd
Diffstat (limited to 'usr.sbin/popa3d/DESIGN')
-rw-r--r-- | usr.sbin/popa3d/DESIGN | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/usr.sbin/popa3d/DESIGN b/usr.sbin/popa3d/DESIGN new file mode 100644 index 00000000000..1d03aad76aa --- /dev/null +++ b/usr.sbin/popa3d/DESIGN @@ -0,0 +1,204 @@ +This file describes the design goals and the reasoning behind some of +the design decisions for my tiny POP3 daemon, popa3d. + + + Why popa3d? + +There're lots of different POP3 servers -- with different feature +sets, performance, and reliability. However, as far as I know, before +I started the work on popa3d, there had been only one with security as +one of its primary design goals: qmail-pop3d. Unfortunately, it would +only work with qmail, and only with its new maildir format. While +both qmail and maildirs do indeed have some advantages, a lot of +people continue running other MTAs, and/or use the older mailbox +format, for various reasons. Many of them need a POP3 server. + + + The design goals. + +Well, the goals themselves are obvious; they're probably the same for +most other POP3 servers as well. It's their priority that differs. +For popa3d, the goals are: + +1. Security (to the extent that is possible with POP3 at all, of course). +2. Reliability (again, as limited by the mailbox format and the protocol). +3. RFC compliance (slightly relaxed to work with real-world POP3 clients). +4. Performance (limited by the more important goals, above). + +Obviously, just like the comments indicate, none of the goals can be met +completely, and balanced decisions need to be made. + + + Security. + +First, it is important that none of the popa3d users get a false sense +of security just because it was the primary design goal. The POP3 +protocol transmits passwords in plaintext, and thus, if you care about +the security of your individual user accounts, should only be used +either in trusted networks, or tunneled over encrypted channels. +There exist extensions to the protocol that are supposed to fix this +problem. I am not supporting them yet, partly because this isn't +going to fully fix the problem. In fact, APOP and the weaker defined +SASL mechanisms such as CRAM-MD5 may potentially be even less secure +than transmission of plaintext passwords because of the requirement +that plaintext equivalents are stored on the server. + +It is also important to understand that nothing can be perfectly +secure. I can make mistakes. While the design of popa3d makes it +harder for those to turn into security holes, this is nevertheless +still possible. + +Having that said, let's get to the security-critical design decisions. + + + Privilege management. + +Initially, popa3d is started as root to handle a connection. However, +it does very little work as root: switching to less privileged UIDs, +communication with child processes, and authentication information +checks (which often involve accessing shadow or master.passwd files). + +The following privilege switches happen during a successful POP3 +session, with /etc/shadow authentication: + + startup as root + | + ----------------- + |child |parent + v v + drop to user popa3d, still as root, + handle the AUTHORIZATION wait for and + state, write the results, - - > read the authentication + and exit information + | + ----------------- + |child |parent + v v + getspnam(3), crypt(3), wait for and + check, write the result, - - > read the authentication + and exit (to clean up) result + | + v + drop to the authenticated user, + handle the TRANSACTION state, + possibly UPDATE the mailbox, + and exit + + + Trust. + +No part of popa3d trusts any information obtained from external +sources (that is, the data is never assumed to be of the expected +format, and is treated as subject to authorization checks). This +includes POP3 commands, mailbox contents, and even popa3d's own +less-privileged child process for the AUTHORIZATION state handling. + + + DoS attacks. + +Just like with most other software, there exist ways to cause a Denial +of Service, by supplying popa3d with an enormous amount of otherwise +valid input. I am aware of the following attacks on popa3d itself: + +1. Connection flood. When running in the standalone mode, popa3d does +quite a few checks to significantly reduce the impact of such attacks +by limiting resource consumption (child processes and logging rate), +while still providing full service for other source IP addresses and +logging everything that might be important. However, when running +from an inetd clone, the handling of these attacks is left up to your +inetd and the kernel. + +2. Huge mailbox sizes, either in message count or bytes. There're +limits in popa3d (see params.h) that are intended to prevent this +attack from stopping the entire service. Depending on your disk and +other quotas, it may still be possible to stop individual users from +getting their mail. + + + Reliability. + +Quoting Dan Bernstein, "the mbox format ... is inherently unreliable". + +While popa3d, just like other mail software that deals with mailboxes, +doesn't guarantee reliability over system crashes, it still makes +sense to talk about its operation on an otherwise stable system. + + + Interaction with other MUAs. + +Similarly to cucipop (but unlike qpopper), popa3d works on the +original mailbox file, without copying. However, unlike cucipop, +popa3d is able to ensure that the mailbox doesn't get corrupted if +another MUA modifies it during the POP session. Before each mailbox +access, popa3d checks its timestamp and, if that has changed, +determines if that is due to new mail that has just been delivered, or +other changes made to the mailbox. In the latter case, the POP +session is silently aborted (which doesn't violate the RFC). popa3d +is careful to make sure the timestamp will change if the mailbox is +written to, by keeping the lock for up to a second if necessary. + + + Mailbox access. + +Except for the total size and message count limits mentioned above +(and you can disable even those), there're no other artificial limits +on the mailbox contents. In particular, there're no line length +limits; unlike with qmail-pop3d, lines don't even need to fit in the +available memory. NUL bytes are allowed in messages as well. + + + Locking. + +Because of dropping to the user "completely" (that is, not even +keeping a GID of mail like some other POP3 servers do), popa3d only +uses fcntl(2) or flock(2) for locking. As a result, it may not be +safe over NFS. This is where I choose security over either +functionality or reliability. + + + RFC compliance. + +I tried to make popa3d as strictly RFC 1939 compliant as possible. +Most other POP3 servers have extra "features" that violate the RFC. +Examples include: wrapping long commands (no matter if they're valid +or not) and thus generating multiple -ERR responses (if not even +worse: processing something from the middle of the line as a command) +to a single command, processing "LIST 4294967297" as "LIST 1" instead +of reporting the error, ignoring past a NUL byte till end of line and +thus misinterpreting the command. While these are mostly harmless, +they can theoretically cause a POP3 client not to detect the +unavailability of a protocol extension. + +There's however one place where popa3d's RFC compliance is +deliberately relaxed: popa3d accepts commands terminated by single +LF's, even though the RFC says the commands are terminated by a CRLF +pair. + + + Performance. + +Despite the two extra "security" fork(2) calls, popa3d seems to behave +fairly efficiently: the efficient mailbox parsing code and the lack of +mailbox copying compensate for the extra fork's. + +Here's some real performance data that I've collected (popa3d running +via inetd; larger sites would use the standalone mode instead): + + 24864 295.50re 16.92cp popa3d* + 12749 4578.88re 15.50cp popa3d + +That is, 12749 POP3 sessions took 32.42 minutes of CPU time (on a 350 +MHz Pentium II); of those, more than a half was spent in the temporary +child processes. It's not that bad though, as this system was running +an (intentionally) expensive crypt(3) that got accounted to the child +/etc/shadow authentication processes. + +Before upgrading to popa3d, the same machine was running qpopper (out +of inetd, too): + + 12025 3169.38re 35.56cp popper + +It used to take a bit more CPU for less POP3 sessions. + +-- +Solar Designer <solar@openwall.com> |