This commit is contained in:
Antonio J. Delgado 2021-09-14 08:39:03 +03:00
parent a589cbdd3d
commit 4a9eda9ca8

View file

@ -1,90 +1,90 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Label a message (add a header) according to certain rules # Label a message (add a header) according to certain rules
# Rules are stored in a file with the format # Rules are stored in a file with the format
# field:match:folder:priority # field:match:folder:priority
import logging import logging
from logging.handlers import SysLogHandler from logging.handlers import SysLogHandler
from logging.handlers import RotatingFileHandler from logging.handlers import RotatingFileHandler
import sys import sys
import pprint import pprint
import re import re
import os import os
import io import io
import email import email
from email.message import EmailMessage from email.message import EmailMessage
from email.parser import HeaderParser from email.parser import HeaderParser
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
messagecontent="".join(sys.stdin.readlines()) messagecontent="".join(sys.stdin.readlines())
log = logging.getLogger() log = logging.getLogger()
log.addHandler(SysLogHandler()) log.addHandler(SysLogHandler())
handler = RotatingFileHandler('/var/spool/filter/labeler.log', maxBytes=1000000, backupCount=5) handler = RotatingFileHandler('/var/spool/filter/labeler.log', maxBytes=1000000, backupCount=5)
formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s') formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter) handler.setFormatter(formatter)
log.addHandler(handler) log.addHandler(handler)
log.setLevel(logging.DEBUG) log.setLevel(logging.DEBUG)
log.info('Writing {} bytes of message in /var/spool/filter/last_message.eml...'.format(len(messagecontent))) log.info('Writing {} bytes of message in /var/spool/filter/last_message.eml...'.format(len(messagecontent)))
if not os.path.exists('/var/spool/filter'): if not os.path.exists('/var/spool/filter'):
log.error('Path /var/spool/filter not found.') log.error('Path /var/spool/filter not found.')
else: else:
with io.open('/var/spool/filter/last_message.eml', 'w') as fp: with io.open('/var/spool/filter/last_message.eml', 'w') as fp:
try: try:
fp.write(messagecontent) fp.write(messagecontent)
except UnicodeEncodeError as e: except UnicodeEncodeError as e:
log.error('There was an Unicode encode error writting file. {}'.format(e)) log.error('There was an Unicode encode error writting file. {}'.format(e))
parser = HeaderParser() parser = HeaderParser()
log.debug('Obtaining headers from message...') log.debug('Obtaining headers from message...')
msg = email.message_from_string(messagecontent) msg = email.message_from_string(messagecontent)
headers = parser.parsestr(messagecontent) headers = parser.parsestr(messagecontent)
log.debug('Headers: {}'.format(", ".join(headers.keys()))) log.debug('Headers: {}'.format(", ".join(headers.keys())))
log.debug('From: {}'.format(headers.get('From',''))) log.debug('From: {}'.format(headers.get('From','')))
log.debug('To: {}'.format(headers.get('To',''))) log.debug('To: {}'.format(headers.get('To','')))
log.debug('Subject: {}'.format(headers.get('Subject',''))) log.debug('Subject: {}'.format(headers.get('Subject','')))
if 'Message-ID' not in headers.keys(): if 'Message-ID' not in headers.keys():
if 'Message-Id' not in headers.keys(): if 'Message-Id' not in headers.keys():
log.warning('Malformed header (no message-id).') log.warning('Malformed header (no message-id).')
else: else:
log.debug('Processing message with ID: {}'.format(headers['Message-Id'])) log.debug('Processing message with ID: {}'.format(headers['Message-Id']))
else: else:
log.debug('Processing message with ID: {}'.format(headers['Message-ID'])) log.debug('Processing message with ID: {}'.format(headers['Message-ID']))
with open('/etc/postfix/filter_rules.conf','r') as fp: with open('/etc/postfix/filter_rules.conf','r') as fp:
strrules = fp.read() strrules = fp.read()
log.debug('Reading general filter rules...') log.debug('Reading general filter rules...')
rules = list() rules = list()
for rule in strrules.split('\n'): for rule in strrules.split('\n'):
if rule != "": if rule != "":
lrule = rule.split(':') lrule = rule.split(':')
field = lrule[0] field = lrule[0]
match = lrule[1] match = lrule[1]
folder = lrule[2] folder = lrule[2]
priority = lrule[4] priority = lrule[4]
rules.append(lrule) rules.append(lrule)
if field in headers.keys(): if field in headers.keys():
m = re.search(match, headers[field]) m = re.search(match, headers[field])
if m is None: if m is None:
a = 1 a = 1
else: else:
msg['X-AD-Label'] = "{}:{}".format(folder, priority) msg['X-AD-Label'] = "{}:{}".format(folder, priority)
log.info('Added label "{}" due to rule "{}"'.format(folder, rule)) log.info('Added label "{}" due to rule "{}"'.format(folder, rule))
messagecontent=msg.as_string() messagecontent=msg.as_string()
if not os.path.exists('/var/spool/filter'): if not os.path.exists('/var/spool/filter'):
log.error('Path /var/spool/filter not found.') log.error('Path /var/spool/filter not found.')
else: else:
log.info('Writing {} bytes of message in /var/spool/filter/last_message_altered.eml...'.format(len(messagecontent))) log.info('Writing {} bytes of message in /var/spool/filter/last_message_altered.eml...'.format(len(messagecontent)))
with open('/var/spool/filter/last_message_altered.eml', 'w', encoding='utf8') as fp: with open('/var/spool/filter/last_message_altered.eml', 'w', encoding='utf8') as fp:
fp.write(messagecontent) fp.write(messagecontent)
args = list() args = list()
args = ["/usr/sbin/sendmail"] + sys.argv args = ["/usr/sbin/sendmail"] + sys.argv
args.pop(1) args.pop(1)
log.debug('Running sendmail with command line: {}'.format(' '.join(args))) log.debug('Running sendmail with command line: {}'.format(' '.join(args)))
if not os.path.exists("/usr/sbin/sendmail"): if not os.path.exists("/usr/sbin/sendmail"):
log.error('Not found sendmail in "/usr/sbin/sendmail"') log.error('Not found sendmail in "/usr/sbin/sendmail"')
else: else:
p = Popen(args, stdin=PIPE) p = Popen(args, stdin=PIPE)
p.communicate(bytearray(messagecontent, 'utf-8')) p.communicate(bytearray(messagecontent, 'utf-8'))