diff --git a/.gitignore b/.gitignore index 4e0bbdf..68ecb9b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ venv/ .idea/ +testing.py + diff --git a/gpgmymail b/gpgmymail index a3c230f..7aecacd 100755 --- a/gpgmymail +++ b/gpgmymail @@ -40,6 +40,13 @@ import gnupg # constants DEFAULT_ENCODING='utf-8' # default is latin-1 which fails w some unicode chars +CONTENT-TRANSFER-ENCODING_TO_ENCODER_DICT = { + "7bit": email.encoders.encode_7or8bit, + "8bit": email.encoders.encode_7or8bit, + "base64": email.encoders.encode_base64, + "quoted-printable": email.encoders.encode_quopri +} +DEFAULT_ENCODER = email.encoders.encode_7or8bit def is_message_encrypted(message: email.message.Message) -> bool: """Determines whether or not an email message is encrypted. @@ -49,6 +56,24 @@ def is_message_encrypted(message: email.message.Message) -> bool: return message.get_content_subtype() == "encrypted" +def get_encoder_from_msg(msg: email.message.Message) -> function: + """ + Return a suitable encoder function from email.encoders based on an input + message. If the input message has no Content-Transfer-Encoding header, + or there is no encoder function corresponding to the CTE header, a default + encoder will be returned. + + :param msg: an unencrypted email Message + :return: function from email.encoders, see + https://docs.python.org/3/library/email.encoders.html + """ + cte = msg.get("Content-Transfer-Encoding") + if cte: + encoder = CONTENT-TRANSFER-ENCODING_TO_ENCODER_DICT.get(cte) + else: + return DEFAULT_ENCODER + return encoder if encoder else DEFAULT_ENCODER + def encrypt( message: email.message.Message, recipients: typing.List[str], @@ -82,13 +107,13 @@ def encrypt( enc = email.mime.application.MIMEApplication( _data=str(encrypted_content).encode(), _subtype="octet-stream", - _encoder=email.encoders.encode_7or8bit + _encoder=get_encoder_from_msg(message) ) control = email.mime.application.MIMEApplication( _data=b'Version: 1\n', _subtype='pgp-encrypted; name="msg.asc"', - _encoder=email.encoders.encode_7or8bit + _encoder=get_encoder_from_msg(message) ) control['Content-Disposition'] = 'inline; filename="msg.asc"'