I’ve been setting up EoC lists on a SELinux postfix box recently. It was rather painless, and I have enough experience with SELinux to quickly write a SELinux policy for EoC. The most difficult thing was that basically file descriptors from the postfix delivery process were inherited all the way to bounces for nonexistant lists.

I tried different setups; using EoC directly in .forward, using procmail, and using a shell wrapper like this:

#!/bin/sh -e
# verify the list exists
/usr/bin/enemies-of-carlotta  --skip-prefix=eoc+ --domain=list.foobar.tld \
  --is-list --name "$RECIPIENT" || exit 67
#  deliver to EOC
exec /usr/bin/enemies-of-carlotta --skip-prefix=eoc+ --domain=list.foobar.tld \
  --incoming --quiet

This last had the drawbacks that I would have to write some additional policy, or maybe make the wrapper part of EoC. With little benefit over the procmail solution. (BTW: IMHO the Debian enemies-of-carlotta package shouldn’t depend on procmail.)

I’ve seen a solution which used a pipe transport from within postfix with a similar wrapper (basically passing $RECIPIENT and $SENDER via commandline instead of having the local delivery agent set them); but I’m not sure about the benefits I get from that (except maybe even more SELinux policy work).

There are two drawbacks with my current solution:

  • Non-existent lists adresses aren’t rejected at SMTP time (can a pipe transport based solution in postfix do that?)
  • Error messages contain the rewritten list address eoc+listname@hostname instead of the real adress (the pipe based solution doesn’t have this drawback)

Hmm… since newer EoC versions now have –sender and –recipient parameters, I guess I’ll try running eoc in the pipe transport without any wrapper now…

Update: I’ve now setup EoC to run as pipe without a wrapper; this didn’t solve the first wish, but caused some extra SELinux violations and despite using the –quiet option a really bad error message for invalid adresses… Patching EoC right now to exit with 67 in that case…

Here’s the diff:

--- /usr/share/enemies-of-carlotta/eoc.py       2005-12-22 01:05:00.000000000 +0100
+++ eoc.py      2006-01-04 19:50:43.000000000 +0100
@@ -1642,7 +1642,17 @@
             debug("Not a mailing list: <%s>" % list_name)
             sys.exit(1)
     elif operation == "--incoming":
-        mlm.incoming_message(skip_prefix, domain, moderate, post)
+        try:
+            mlm.incoming_message(skip_prefix, domain, moderate, post)
+        except BadCommandAddress:
+            sys.stderr.write("Bad command address.\n")
+            sys.exit(os.EX_NOUSER)
+        except BadSignature:
+            sys.stderr.write("Bad signature.\n")
+            sys.exit(os.EX_NOPERM)
+        except UnknownList:
+            sys.stderr.write("Unknown list.\n")
+            sys.exit(os.EX_NOUSER)
     elif operation == "--cleaning-woman":
         mlm.cleaning_woman()
     elif operation == "--show-lists":

which works much better when used as transport like this:

eoc       unix  -       n       n       -       3       pipe
        flags=R user=eoc-lists argv=/usr/bin/enemies-of-carlotta --sender=${sender} --recipient=${recipient} --incoming