diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..130d66a --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +venv +__pycache__ +config.key +spamsubmit.conf +.idea \ No newline at end of file diff --git a/passencrypt.py b/passencrypt.py new file mode 100644 index 0000000..a1b298a --- /dev/null +++ b/passencrypt.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os.path +from cryptography.fernet import Fernet +from getpass import getpass + + +def get_key() -> bytes: + key_file = 'config.key' + if os.path.exists(key_file): + with open(key_file, 'rb') as f: + key = f.read() + return key + else: + key = Fernet.generate_key() + with open(key_file, 'wb') as f: + f.write(key) + return key + + +def encrypt(password: str) -> str: + key = get_key() + encrypted = Fernet(key).encrypt(password.encode('UTF-8')) + return encrypted.decode('UTF-8') + + +def decrypt(encrypted: str): + key = get_key() + return Fernet(key).decrypt(encrypted).decode('UTF-8') + + +if __name__ == '__main__': + password = getpass() + print(encrypt(password)) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..344a30a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +cryptography~=38.0.3 +IMAPClient~=2.3.1 \ No newline at end of file diff --git a/spamsubmit.py b/spamsubmit.py new file mode 100644 index 0000000..b0112d9 --- /dev/null +++ b/spamsubmit.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import configparser +import email +import logging +import smtplib +import sys +from email.message import Message +from email.mime.base import MIMEBase +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText + +from imapclient import IMAPClient +import passencrypt + +config = configparser.ConfigParser() +config.read(sys.argv[1]) + +logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s') + + +def print_folders(): + for (flags, delimiter, name) in imap.list_folders(): + print(name) + + +def process_new_messages(): + logging.info('Processing new messages') + imap.select_folder(config['folders']['to_submit']) + messages = imap.search() + for uid, message_data in imap.fetch(messages, "RFC822").items(): + email_message = email.message_from_bytes(message_data[b"RFC822"]) + print(uid, email_message.get("From"), email_message.get("Subject")) + submit_spam(email_message) + imap.move(uid, config['folders']['submitted']) + + +def submit_spam(spam: Message): + message = email.mime.multipart.MIMEMultipart() + message["From"] = config['smtp']['sender'] + message["To"] = config['spamcop']['to'] + message["Subject"] = config['spamcop']['subject'] + message.attach(MIMEText(config['spamcop']['message'], "plain")) + + part = MIMEBase("message", "rfc822") + part.set_payload(spam.as_string()) + part.add_header("Content-Disposition", "attachment; filename=\"message.eml\"") + message.attach(part) + + with smtplib.SMTP_SSL(config["smtp"]["host"], int(config["smtp"]["port"])) as server: + server.login(config["smtp"]["username"], passencrypt.decrypt(config['smtp']['password'])) + server.sendmail(message["From"], message["To"], message.as_string()) + + imap.append('Junk.Sent', message.as_string()) + + +def run(): + global imap + imap = IMAPClient(config['imap']['host'], use_uid=True) + imap.login(config['imap']['username'], passencrypt.decrypt(config['imap']['password'])) + imap.select_folder(config['folders']['to_submit']) + process_new_messages() + while True: + try: + imap.idle() + responses = imap.idle_check(timeout=600) + for (size, message) in responses: + if message.decode('UTF-8') == 'EXISTS' and size>0: + process_new_messages() + except KeyboardInterrupt: + break + finally: + imap.idle_done() + logging.info('Terminating') + imap.logout() + + +if __name__ == '__main__': + run() \ No newline at end of file