mirror of
https://github.com/chillout2k/gulag.git
synced 2025-12-13 16:00:18 +00:00
RSPAMD HTTP2IMAP relay
This commit is contained in:
parent
71d6b0b200
commit
05939e8732
72
app/Gulag.py
72
app/Gulag.py
@ -35,9 +35,9 @@ class Gulag:
|
||||
except GulagDBException as e:
|
||||
raise GulagException(e.message) from e
|
||||
|
||||
# Iterate through all mailboxes, extract metadata
|
||||
# from all unseen mails and import them into database
|
||||
def import_quarmails(self):
|
||||
# Alle Mailboxes durchiterieren und die Meta-Infos aller neuen (unseen)
|
||||
# Nachrichten in die Datenbank importieren
|
||||
for mailbox in self.db.get_mailboxes():
|
||||
imap_mb = None
|
||||
try:
|
||||
@ -81,14 +81,21 @@ class Gulag:
|
||||
except:
|
||||
pass
|
||||
x_spam_status = email.header.decode_header(msg['X-Spam-Status'])[0][0]
|
||||
mx_queue_id = "n.a."
|
||||
try:
|
||||
mx_queue_id = email.header.decode_header(msg['X-Spam-QID'])[0][0]
|
||||
except:
|
||||
pass
|
||||
r5321_rcpts = str(r5321_rcpts).lower()
|
||||
r5321_rcpts = r5321_rcpts.replace(" ", "")
|
||||
r5321_rcpts = r5321_rcpts.replace("<", "")
|
||||
r5321_rcpts = r5321_rcpts.replace(">", "")
|
||||
# Pro Envelope-RCPT einen Eintrag in die DB schreiben.
|
||||
# Die E-Mail im IMAP-Backend existiert jedoch nur ein Mal und wird
|
||||
# über die mailbox_id sowie die imap_uid mehrfach referenziert.
|
||||
for r5321_rcpt in r5321_rcpts.split(","):
|
||||
quarmail_id = self.db.add_quarmail({
|
||||
'mx_queue_id': 'queue_id', 'env_from': r5321_from, 'env_rcpt': r5321_rcpt,
|
||||
'mx_queue_id': mx_queue_id, 'env_from': r5321_from, 'env_rcpt': r5321_rcpt,
|
||||
'hdr_cf': x_spam_status, 'hdr_from': r5322_from, 'hdr_subject': subject,
|
||||
'hdr_msgid': msg_id, 'hdr_date': date, 'cf_meta': 'cf_meta',
|
||||
'mailbox_id': 'quarantine@zwackl.de', 'imap_uid': uid, 'msg_size': msg_size
|
||||
@ -142,7 +149,7 @@ class Gulag:
|
||||
except GulagDBException as e:
|
||||
raise GulagException("GulagDBException: " + e.message) from e
|
||||
|
||||
def rspamd_http2smtp(self,mailbox_id):
|
||||
def rspamd_http2imap(self,mailbox_id):
|
||||
mailbox = None
|
||||
try:
|
||||
mailbox = self.db.get_mailbox(mailbox_id)
|
||||
@ -151,31 +158,50 @@ class Gulag:
|
||||
|
||||
if(request.headers.get('X-Rspamd-From') == None):
|
||||
raise GulagException("Missing Rspamd-specific headers (e.g. X-Rspamd-From)!")
|
||||
|
||||
# recompose rejected mail that will be sent to quarantine mailbox
|
||||
#FIXME: print("mx_queue_id: " + request.headers.get('X-Rspamd-Qid'))
|
||||
msg = None
|
||||
try:
|
||||
msg = email.message_from_string(request.get_data(as_text=True))
|
||||
rcpts_hdr = str(request.headers.get('X-Rspamd-Rcpt'))
|
||||
# FIXME: special chars []" rausstrippen! -> JSON!!!
|
||||
print("RCPTs neu: " + rcpts_hdr)
|
||||
msg.add_header("X-Envelope-To-Blocked", rcpts_hdr)
|
||||
msg.add_header("X-Spam-Status", request.headers.get('X-Rspamd-Symbols'))
|
||||
# except email.errors.* as e:
|
||||
rcpts_hdr = ""
|
||||
for rcpt in json.loads(str(request.headers.get('X-Rspamd-Rcpt'))):
|
||||
if(len(rcpts_hdr) > 0):
|
||||
rcpts_hdr = rcpts_hdr + "," + rcpt
|
||||
else:
|
||||
rcpts_hdr = rcpt
|
||||
msg = "Return-Path: <" + request.headers.get('X-Rspamd-From') + ">\r\n"
|
||||
msg = msg + "Received: from rspamd_http2imap relay by gulag-mailbox " + mailbox_id + "\r\n"
|
||||
msg = msg + "X-Envelope-To-Blocked: " + rcpts_hdr + "\r\n"
|
||||
msg = msg + "X-Spam-Status: " + request.headers.get('X-Rspamd-Symbols') + "\r\n"
|
||||
msg = msg + "X-Spam-QID: " + request.headers.get('X-Rspamd-Qid') + "\r\n"
|
||||
msg = msg + request.get_data(as_text=True)
|
||||
#FIXME: except email.errors.* as e:
|
||||
except:
|
||||
raise GulagException(str(sys.exc_info()))
|
||||
|
||||
# Use IMAP´s APPEND command to store the message into mailbox
|
||||
imap_mb = None
|
||||
try:
|
||||
with SMTP(host=mailbox['smtp_server'],port=mailbox['smtp_port']) as smtp:
|
||||
try:
|
||||
smtp.sendmail(
|
||||
request.headers.get('X-Rspamd-From'),
|
||||
mailbox_id,
|
||||
msg.as_string()
|
||||
imap_mb = IMAPmailbox(
|
||||
mailbox['imap_server'],
|
||||
mailbox['imap_user'],
|
||||
mailbox['imap_pass'],
|
||||
mailbox['imap_mailbox']
|
||||
)
|
||||
except (SMTPRecipientsRefused,SMTPHeloError,SMTPSenderRefused,SMTPDataError) as e:
|
||||
raise GulagException(str(e)) from e
|
||||
except TimeoutError as e:
|
||||
raise GulagException(str(e)) from e
|
||||
imap_mb.append_message(msg)
|
||||
except IMAPmailboxException as e:
|
||||
raise GulagException(e.message) from e
|
||||
# try:
|
||||
# if not mailbox['smtp_server']:
|
||||
# raise GulagException("No SMTP server configured for mailbox " + mailbox_id)
|
||||
# # FIXME: SMTP tranaport security and authentication!
|
||||
# with SMTP(host=mailbox['smtp_server'],port=mailbox['smtp_port']) as smtp:
|
||||
# try:
|
||||
# smtp.sendmail(
|
||||
# request.headers.get('X-Rspamd-From'),
|
||||
# mailbox_id,
|
||||
# msg
|
||||
# )
|
||||
# except (SMTPRecipientsRefused,SMTPHeloError,SMTPSenderRefused,SMTPDataError) as e:
|
||||
# raise GulagException(str(e)) from e
|
||||
# except TimeoutError as e:
|
||||
# raise GulagException(str(e)) from e
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import imaplib
|
||||
import email
|
||||
import email.header
|
||||
import time
|
||||
|
||||
class IMAPmailboxException(Exception):
|
||||
message = None
|
||||
@ -71,19 +72,29 @@ class IMAPmailbox:
|
||||
msg = email.message_from_bytes(data[0][1])
|
||||
for part in msg.walk():
|
||||
if part.get_filename():
|
||||
# ist ein Attachment
|
||||
# let´s define parts with filename as attachments
|
||||
filename = email.header.decode_header(part.get_filename())
|
||||
if filename[0][1]:
|
||||
# Encoded
|
||||
# Encoded -> decode
|
||||
filename = filename[0][0].decode(filename[0][1])
|
||||
else:
|
||||
# Nicht encoded
|
||||
# not encoded
|
||||
filename = filename[0][0]
|
||||
results.append({
|
||||
'filename': filename,
|
||||
'content-type': part.get_content_type(), # Ist das wirklich wahr?
|
||||
'content-type': part.get_content_type(),
|
||||
'content': part.get_payload(decode=True)
|
||||
})
|
||||
# Ende if part.get_filename()
|
||||
# End if part.get_filename()
|
||||
return results
|
||||
|
||||
def append_message(self,message):
|
||||
rv, data = self.mailbox.append(
|
||||
self.imap_mailbox,
|
||||
'UNSEEN',
|
||||
imaplib.Time2Internaldate(time.time()),
|
||||
str(message).encode('utf-8')
|
||||
)
|
||||
if rv != 'OK':
|
||||
raise IMAPmailboxException("ERROR appending message!")
|
||||
|
||||
|
||||
@ -64,9 +64,9 @@ class ResAttachment(GulagResource):
|
||||
class ResRSPAMDImporter(GulagResource):
|
||||
def post(self,mailbox_id):
|
||||
try:
|
||||
self.gulag.rspamd_http2smtp(mailbox_id)
|
||||
self.gulag.rspamd_http2imap(mailbox_id)
|
||||
# TODO: Response mit Location-Header?
|
||||
return {"resource: ": "HTTP2SMTP for RSPAMD"}
|
||||
return {"resource: ": "HTTP2IMAP for RSPAMD"}
|
||||
except GulagException as e:
|
||||
abort(400, message=e.message)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user