2024-05-29 21:37:40 -07:00
|
|
|
#!/opt/mailman/venv/bin/python3
|
2024-05-29 20:46:44 -07:00
|
|
|
#
|
|
|
|
# Written by Thomas Schneider <qsuscs@qsuscs.de>
|
|
|
|
# This script is placed in public domain. If this is not applicable, consider
|
|
|
|
# it licensed under the CC-0:
|
|
|
|
# <https://creativecommons.org/publicdomain/zero/1.0/>
|
|
|
|
|
2024-05-29 21:37:40 -07:00
|
|
|
# Command Line Arguments (reverse engineered)
|
|
|
|
# $1 LMTP Port
|
|
|
|
# $2 ????
|
|
|
|
# $3 LMTP Host
|
|
|
|
# std_in message text
|
|
|
|
|
2024-05-29 21:44:19 -07:00
|
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
2024-05-29 22:46:44 -07:00
|
|
|
# Format time and message
|
|
|
|
FORMAT = '%(asctime)s %(message)s'
|
|
|
|
# Set Date Format
|
2024-05-29 22:49:41 -07:00
|
|
|
DATEFMT = '%Y-%m-%d %H:%M:%S %Z'
|
2024-05-29 22:46:44 -07:00
|
|
|
LEVEL=logging.INFO
|
|
|
|
LOGFILE='/opt/mailman/logs/courier-to-mailman.log'
|
|
|
|
logging.basicConfig(filename=LOGFILE, level=LEVEL, format=FORMAT, datefmt=DATEFMT)
|
2024-05-29 22:33:39 -07:00
|
|
|
|
2024-05-29 20:46:44 -07:00
|
|
|
try:
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import smtplib
|
2024-05-30 00:40:35 -07:00
|
|
|
from email.parser import HeaderParser
|
2024-05-30 01:13:23 -07:00
|
|
|
import pprint
|
2024-05-29 20:46:44 -07:00
|
|
|
|
2024-05-29 21:44:19 -07:00
|
|
|
logger.info('Starting Logging (inside try)')
|
2024-05-29 21:37:40 -07:00
|
|
|
|
|
|
|
# Setup LTMP connection
|
2024-05-29 20:46:44 -07:00
|
|
|
lmtp_host = sys.argv[3] if len(sys.argv) > 3 else 'localhost'
|
2024-05-29 23:03:16 -07:00
|
|
|
lmtp_port = sys.argv[1] if len(sys.argv) > 1 else 8024
|
|
|
|
logger.info('lmtp_host: %s lmtp_port: %s', lmtp_host, lmtp_port)
|
2024-05-29 21:37:40 -07:00
|
|
|
# class smtplib.LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None)
|
2024-05-29 23:03:16 -07:00
|
|
|
logger.info('lmtp_port: %s', lmtp_port)
|
|
|
|
lmtp = smtplib.LMTP(lmtp_host, int(lmtp_port))
|
2024-05-29 23:57:57 -07:00
|
|
|
logger.info('lmtp_port (lmtp setup): %s', lmtp_port)
|
2024-05-29 20:46:44 -07:00
|
|
|
|
|
|
|
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()
|
2024-05-30 01:17:01 -07:00
|
|
|
content = content.replace(b'\r\n', b'\n').replace(b'\r', b'\n').replace(b'\n', b'\r\n')
|
2024-05-30 00:40:35 -07:00
|
|
|
header = content.strip()
|
2024-05-30 01:07:44 -07:00
|
|
|
headers = dict(HeaderParser().parsestr(header.decode('utf-8')))
|
2024-05-30 01:13:23 -07:00
|
|
|
header_to = headers['To']
|
2024-05-29 20:46:44 -07:00
|
|
|
|
|
|
|
# See <https://qmail.notqmail.org/qmail-manual-html/man8/qmail-command.html>
|
|
|
|
# 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.
|
2024-05-30 00:04:20 -07:00
|
|
|
arg_ext_tmp = sys.argv[2] if len(sys.argv) > 2 else "1"
|
|
|
|
arg_ext = arg_ext_tmp if arg_ext_tmp != "1" else ""
|
2024-05-29 20:46:44 -07:00
|
|
|
lmtp.sendmail(
|
|
|
|
os.environ['SENDER'],
|
2024-05-30 00:59:35 -07:00
|
|
|
header_to,
|
2024-05-29 20:46:44 -07:00
|
|
|
#sys.stdin.buffer.read()
|
|
|
|
content
|
|
|
|
)
|
|
|
|
except smtplib.SMTPResponseException as e:
|
2024-05-30 01:23:33 -07:00
|
|
|
logger.error('lmtp error on send')
|
|
|
|
logger.exception('Got exception Traceback:')
|
|
|
|
logger.error('lmtp failed errorno: %s, message: %s', e.errno, e.strerror)
|
2024-05-29 20:46:44 -07:00
|
|
|
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
|
2024-05-29 23:48:26 -07:00
|
|
|
except Exception as e:
|
2024-05-29 23:36:07 -07:00
|
|
|
logger.error('lmtp error')
|
2024-05-29 23:53:45 -07:00
|
|
|
logger.exception('Got exception Traceback:')
|
2024-05-29 23:40:08 -07:00
|
|
|
logger.error('lmtp failed errorno: %s, message: %s', e.errno, e.strerror)
|
2024-05-30 01:27:14 -07:00
|
|
|
exit(100)
|
|
|
|
|
|
|
|
logger.info('Bottom of script, ending log')
|