Postmaster ESMTP Server
=======================
:Latest Release: postmaster-0.1.tar.gz_
:Darcs: darcs_ get http://postmaster.cryp.to/ postmaster
.. contents::
The Sales Pitch
---------------
Postmaster is the mail transport agent of choice for the
discriminating hacker. Or, to be more accurate: for the
discriminating Haskell_ hacker, because if you don't know
any Haskell, you have about zero chance of running this
software right now. I plan on turning Postmaster into
something an end-user can run, but that's a long road.
So why yet *another* MTA? Aren't Sendmail, Qmail, Postfix,
and Exim enough already?
No, unfortunately they are not, because none of those
programs comes even close to the degree of configurability
I need. Postmaster allows you to configure *anything*. I
really mean it. You'd like to configure your MTA to do
mail relaying for the site ``example.org`` only on
Saturdays in a leap year? No problem at all. You'd like to
put your entire mail configuration into a DNS zone and
distribute it through the domain name system to your mail
exchangers? Be my guest. You'd like to rewrite the word
"no" to "yes" in any e-mail you receive which has
"Michelle" in the ``From:`` header and was sent between
8am and 10am CET? Sure thing.
Postmaster is not really an MTA, it is a framework in
which you can easily write your own, custom-built MTA!
This means that Postmaster contains everything *except
for* the routine ``main``. That's what you have to write.
What can it do?
'''''''''''''''
Postmaster implements an ESMTP server. Given a
configuration, it starts up and listens for incoming SMTP
connections, handles them, and pipes the accepted e-mail
messages into an arbitrary local mailer of your choice. A
good local mailer is Procmail_.
Beyond that, you can configure and modify every little
step of the SMTP transaction. All the real work is done
through a call-back function. Postmaster triggers an
"event" every time a state change is required, and hopes
that the call-back does whatever is necessary. Among the
known events, this one is popular::
AddRcptTo Mailbox
So by writing a handler function for this event, you can
configure what user addresses the server will accept. For
example::
joe, jane :: Mailbox
joe = Mailbox [] "joe" "example.net"
jane = Mailbox [] "jane" "example.net"
admin :: Mailbox
admin = Mailbox [] "janes.husband" "example.com"
event :: Event -> Smtpd SmtpReply
event (AddRcptTo mbox)
| mbox == joe = procmail mbox "joe" []
| mbox == jane = do
from <- gets mailFrom
when (from == joe)
(relay [admin] >> return ())
procmail mbox "jane" []
| otherwise = say 5 5 3 "unknown recipient"
You could also read that configuration from a file, query
the DNS for that recipient, or accept / refuse addresses
randomly. It's entirely up to you.
Postmaster provides a wealth of SMTP-related functions you
can use. You can (asynchronously) resolve ``A``, ``PTR``,
or ``MX`` records. There is a generic, type-safe Unix-like
environment for each session and a global one for the
entire daemon in which you can store any data your event
handler needs. Postmaster provides a framework for logging
messages through ``syslog(3)``. And, last but not least,
there is a rapidly growing collection of re-usable event
handlers which you can plug together to configure complex
setups in a few lines of code.
What can it *not* do?
'''''''''''''''''''''
At the moment, Postmaster has no mail queue. Until that is
implemented, there is no way to deliver outbound messages
via SMTP. If you have to relay e-mail for others, you will
need another MTA installed to do that. Sendmail_ is
particularly well suited for the task. Just modify your
``sendmail.mc`` file to contain the lines ::
FEATURE(no_default_msa)
dnl DAEMON_OPTIONS(`Port=25, Name=MTA')
DAEMON_OPTIONS(`Port=587, Name=MSA, M=E')
and your ``submit.mc`` file to contain::
FEATURE(`msp', `', `MSA')
This configures Sendmail to act as a "mail submission
agent". Meaning that it will not listen on port 25 but on
port 587 instead. Correspondingly, your local mail system
will not inject messages via ``localhost:25`` but
``localhost:587``. You'll effectively use Postmaster as
your MTA to the outside world, and Sendmail as your MTA on
the inside. It's not beautiful, but it will work very
reliably until Postmaster's own delivery agent is ready.
Documentation
-------------
`Postmaster Tutorial`_
A walk through "Config.hs" -- this is work in progress.
`Reference Documentation`_
Haddock-generated reference of all exported functions.
Building Postmaster
-------------------
To compile the software, you need GHC_ version 6.6 or
later (only tested with GHC 6.8.x). Furthermore, you'll
need the `GNU adns`_ and OpenSSL_ C libraries installed.
You can install through your distro, if it provides postmaster,
or from source. The source can be gotten from the Darcs repo or
Hackage.
Once you've fetched the sources, do the following:
1) Build and install through Cabal as for other Haskell packages:
runhaskell Setup configure --user --prefix=$HOME
runhaskell Setup build
runhaskell Setup install --user
(You may want to remove the --user flag when installing as root.)
You can also install via the GNU Autotools.
1) Edit ``GNUmakefile`` to fit your system. You'll have to
adapt the variable ``HDI_PATH`` to point to the base
directory where the Haddock interface files for your
compiler are installed or the documentation won't
(re-)build.
2) Say ``make``. You need GNU make to build Postmaster, so
if you're running a BSD Unix, ``gmake`` should be used
instead.
3) If you get this compiler error::
.objs/Digest.o(.text+0x357): In function `spyU_info':
: undefined reference to `EVP_mdc2'
then your OpenSSL version doesn't contain the MDC2 hash
algorithm yet. That's no problem ... just comment out
the (three or so) references to it in
``hopenssl/Digest.hs`` -- or upgrade to OpenSSL 0.9.7e
or later.
Copyleft
--------
Copyright (c) 2008 Peter Simons <simons@cryp.to>. All
rights reserved. This software is released under the terms
of the `GNU General Public License
<http://www.gnu.org/licenses/gpl.html>`_.
-----------------------------------------------------------------
`[Homepage] <http://cryp.to/>`_
.. _Haskell: http://haskell.org/
.. _darcs: http://darcs.net/
.. _Reference Documentation: docs/index.html
.. _Procmail: http://www.procmail.org/
.. _Sendmail: http://sendmail.org/
.. _postmaster-0.1.tar.gz: http://postmaster.cryp.to/postmaster-0.1.tar.gz
.. _GHC: http://haskell.org/ghc/
.. _GNU adns: http://www.gnu.org/software/adns/
.. _OpenSSL: http://www.openssl.org/
.. _Postmaster Tutorial: docs/tutorial.html