summaryrefslogtreecommitdiff
path: root/usr.sbin/popa3d/DESIGN
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2001-08-19 13:05:58 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2001-08-19 13:05:58 +0000
commita6a38350f779ddf3a6febf67dda7714fe368e492 (patch)
treeb8ffbc248c20776618b1d6aa93ec16abb19e78d1 /usr.sbin/popa3d/DESIGN
parent580e400b41d341c2ad1bfe153d5ca6553351703a (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/DESIGN204
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>