first attempt to implement decoding as 7or8bit through quopri, base64, and byte replacement

This commit is contained in:
revsuine 2024-11-14 18:13:16 +00:00
parent 8755e0e1cc
commit e7a8f40b91
Signed by: revsuine
GPG key ID: 3F257B68F5BC9339

View file

@ -34,12 +34,16 @@ import email.mime.application
import email.mime.multipart import email.mime.multipart
import email.mime.message import email.mime.message
import typing import typing
# for decode_email:
import quopri
import base64
# see: https://gnupg.readthedocs.io/en/latest/ # see: https://gnupg.readthedocs.io/en/latest/
import gnupg import gnupg
# constants # constants
DEFAULT_ENCODING='utf-8' # default is latin-1 which fails w some unicode chars DEFAULT_ENCODING='utf-8' # default is latin-1 which fails w some unicode chars
CTES_TO_BE_DECODED = ("quoted-printable", "base64")
def is_message_encrypted(message: email.message.Message) -> bool: def is_message_encrypted(message: email.message.Message) -> bool:
"""Determines whether or not an email message is encrypted. """Determines whether or not an email message is encrypted.
@ -55,19 +59,43 @@ def decode_email(message: email.message.Message) -> email.message.Message:
:param message: email.message.Message to be decoded :param message: email.message.Message to be decoded
:return: decoded email.message.Message""" :return: decoded email.message.Message"""
if message.is_multipart(): # this is a kinda hacky way to do this by manipulating the message as a
payload = [] # string but i couldn't get it to work any other way
for part in message.walk():
if not part.is_multipart():
payload.append(part.get_payload(decode=True))
message.set_payload(payload) msg_ctes = message.get_all("Content-Transfer-Encoding")
else:
message.set_payload(message.get_payload(decode=True)) # this list will be populated with any encoding that needs to be decoded,
# e.g. base64
# empty if no decoding needed
# set used to avoid dupes
decodes_needed = set()
# check if any of the parts of the message need decoding
for cte in CTES_TO_BE_DECODED:
if cte in msg_ctes:
decodes_needed.add(cte)
# no decoding needed, go ahead with message
if not decodes_needed:
return message
message["Content-Transfer-Encoding"] = "7bit" # decoding needed:
# as_string() gives us str, encode() gives us bytes
decoded_bytes = msg.as_string().encode()
if "quoted-printable" in decodes_needed:
decoded_bytes = quopri.decodestring(decoded_bytes)
if "base64" in decodes_needed:
decoded_bytes = base64.b64decode(decoded_bytes)
return message # replace any instances of the Content-Transfer-Encoding header
decoded_bytes = decoded_bytes.replace(
b'Content-Transfer-Encoding: quoted-printable',
b'Content-Transfer-Encoding: 7bit'
)
decoded_bytes = decoded_bytes.replace(
b'Content-Transfer-Encoding: base64',
b'Content-Transfer-Encoding: 7bit'
)
return email.message_from_bytes(decoded_bytes)
def encrypt( def encrypt(
message: email.message.Message, message: email.message.Message,