#!/opt/mailman/venv/bin/python3 # # Written by Thomas Schneider # This script is placed in public domain. If this is not applicable, consider # it licensed under the CC-0: # # Command Line Arguments (reverse engineered) # $1 LMTP Port # $2 ???? # $3 LMTP Host # std_in message text import logging logger = logging.getLogger(__name__) # Format time and message FORMAT = '%(asctime)s %(message)s' # Set Date Format DATEFMT = '%Y-%m-%d %H:%M:%S %Z' LEVEL=logging.INFO LOGFILE='/opt/mailman/logs/courier-to-mailman.log' logging.basicConfig(filename=LOGFILE, level=LEVEL, format=FORMAT, datefmt=DATEFMT) try: import os import sys import smtplib from email.parser import HeaderParser import pprint logger.info('Starting Logging (inside try)') # Setup LTMP connection lmtp_host = sys.argv[3] if len(sys.argv) > 3 else 'localhost' lmtp_port = sys.argv[1] if len(sys.argv) > 1 else 8024 logger.info('lmtp_host: %s lmtp_port: %s', lmtp_host, lmtp_port) # class smtplib.LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None) logger.info('lmtp_port: %s', lmtp_port) lmtp = smtplib.LMTP(lmtp_host, int(lmtp_port)) logger.info('lmtp_port (lmtp setup): %s', lmtp_port) try: # Unfortunately qmail sends to local bare LF for end line, while # SMTP requires CRLF, so normalize to that. Error message without this: # "Line too long (see RFC5321 4.5.3.1.6)" # https://gitlab.com/mailman/mailman/-/issues/1133 content = sys.stdin.buffer.read() content = content.replace(b'\r\n', b'\n').replace(b'\r', b'\n').replace(b'\n', b'\r\n') header = content.strip() headers = dict(HeaderParser().parsestr(header.decode('utf-8'))) header_to = headers['To'] # See # for qmail command docs and supplied environment variables. # We need to replace "1" with an empty string, as qmail only supports EXT, # EXT2, EXT3, EXT4. arg_ext_tmp = sys.argv[2] if len(sys.argv) > 2 else "1" arg_ext = arg_ext_tmp if arg_ext_tmp != "1" else "" lmtp.sendmail( os.environ['SENDER'], header_to, #sys.stdin.buffer.read() content ) except smtplib.SMTPResponseException as e: logger.error('lmtp error on send') logger.exception('Got exception Traceback:') logger.error('lmtp failed errorno: %s, message: %s', e.errno, e.strerror) if 400 <= e.smtp_code < 500: exit(111) # otherwise, it's either a 5xx aka permanent error or something else # is already b0rked, thus raise -> exit(100) -> have qmail return a # 5xx error else: raise except Exception as e: logger.error('lmtp error') logger.exception('Got exception Traceback:') logger.error('lmtp failed errorno: %s, message: %s', e.errno, e.strerror) exit(100) logger.info('Bottom of script, ending log')