0

I have some servers that create automated emails which all pass through a Postfix MTA. The software that generates the email does not strictly follow RFCs, and sometimes generates emails with duplicate message-ID headers. The software cannot be changed, so I am trying to intercept and fix these messages on their way through the MTA.

I have a milter daemon written in Python that is attempting to remove duplicate message IDs from inbound messages.

The code is below:

import Milter
import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

file_handler = logging.FileHandler('/var/log/milter.log')
file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
logger.addHandler(file_handler)

seen_message_ids = set()

class MessageIDMilter(Milter.Base):
    def __init__(self):
        self.id = Milter.uniqueID()

    @Milter.noreply
    def connect(self, IPname, family, hostaddr):
        logger.debug("Milter connected to %s family %s at address %s" % (IPname, family, hostaddr))
        self.IPname = IPname
        self.family = family
        self.hostaddr = hostaddr
        return Milter.CONTINUE

    @Milter.noreply
    def header(self, name, hval):
        logger.debug("Received header %s with value %s" % (name, hval))
        if name.lower() == "message-id":
            logger.debug("Found message ID: %s" % hval)
            if hval in seen_message_ids:
                logger.debug("Deleting duplicate message ID: %s" % hval)
                try:
                    self.chgheader(name, 1, "")
                except Exception as e:
                    logger.error("Error removing from: %s error message: %s" % (name, e))


            else:
                seen_message_ids.add(hval)
        return Milter.CONTINUE

    @Milter.noreply
    def eoh(self):
        logger.debug("Reached end of headers")
        return Milter.ACCEPT

if __name__ == "__main__":
    logger.debug("Script started OK")
    Milter.factory = MessageIDMilter
    Milter.runmilter("message-id-milter", "inet:10001@localhost", 0)

The script runs and can be called from Postfix. When attempting to delete the duplicate header with chgheader, the following error is thrown:

2023-02-03 18:22:44,983 ERROR Error removing from: Message-ID error message: cannot change header

I cannot see anything wrong with this request, nor any other method to remove the header. The docs suggest this should work: https://pythonhosted.org/pymilter/milter_api/smfi_chgheader.html

btongeorge
  • 421
  • 2
  • 12
  • 23
  • Does it work with other headers? If so, then you probably can't change Message-ID. My expectation is that the Message-ID is how the message is identified internally and changing it would require some internal data structures to be updated, and the authors of Postfix didn't want to deal with that. – kindall Feb 03 '23 at 18:42
  • The weird thing is that the message IDs are the same, the header is just duplicated exactly. Also it's the Python script that errors, before it returns control to Postfix. – btongeorge Feb 04 '23 at 19:17
  • Yes, my hypothesis is that the Python library knows about this limitation of Postfix and enforces it. But I might be hypothesizing wrong, of course. – kindall Feb 06 '23 at 18:52

0 Answers0