1313from django .core .mail .message import EmailMultiAlternatives
1414from django .utils .encoding import smart_text
1515
16+ from .handlers import (handle_failed_message_encryption ,
17+ handle_failed_alternative_encryption ,
18+ handle_failed_attachment_encryption )
1619from .settings import (GNUPG_HOME , GNUPG_ENCODING , USE_GNUPG , encrypt_kwargs )
1720from .utils import EncryptionFailedError
1821
@@ -39,14 +42,6 @@ def open(self, body):
3942 webbrowser .open ("file://" + temp .name )
4043
4144
42- class AttachmentEncryptionFailedError (EncryptionFailedError ):
43- pass
44-
45-
46- class AlternativeEncryptionFailedError (EncryptionFailedError ):
47- pass
48-
49-
5045if USE_GNUPG :
5146 from gnupg import GPG
5247
@@ -102,12 +97,22 @@ def encrypt_attachment(address, attachment, use_asc):
10297 try :
10398 encrypted_content = encrypt (content , address )
10499 except EncryptionFailedError as e :
105- # SECURITY: We could include a piece of the content here, but that
106- # would leak information in logs and to the admins. So instead, we
107- # only try to include the filename.
108- raise AttachmentEncryptionFailedError (
109- "Encrypting attachment to %s failed: %s (%s)" , address ,
110- filename , e .msg )
100+ # This function will need to decide what to do. Possibilities include
101+ # one or more of:
102+ #
103+ # * Mail admins (possibly without encrypting the message to them)
104+ # * Remove the offending key automatically
105+ # * Set the body to a blank string
106+ # * Set the body to the cleartext
107+ # * Set the body to the cleartext, with a warning message prepended
108+ # * Set the body to a custom error string
109+ # * Reraise the exception
110+ #
111+ # However, the behavior will be very site-specific, because each site
112+ # will have different attackers, different threat profiles, different
113+ # compliance requirements, and different policies.
114+ #
115+ handle_failed_attachment_encryption (e )
111116 else :
112117 if use_asc and filename is not None :
113118 filename += ".asc"
@@ -145,7 +150,10 @@ def encrypt_messages(email_messages):
145150 continue
146151
147152 # Replace the message body with the encrypted message body
148- new_msg .body = encrypt (new_msg .body , address )
153+ try :
154+ new_msg .body = encrypt (new_msg .body , address )
155+ except EncryptionFailedError as e :
156+ handle_failed_message_encryption (e )
149157
150158 # If the message has alternatives, encrypt them all
151159 alternatives = []
@@ -159,9 +167,7 @@ def encrypt_messages(email_messages):
159167 encrypted_alternative = encrypt (alt , address ,
160168 ** encrypt_kwargs )
161169 except EncryptionFailedError as e :
162- raise AlternativeEncryptionFailedError (
163- "Encrypting alternative to %s failed: %s (%s)" ,
164- address , alt , e .msg )
170+ handle_failed_alternative_encryption (e )
165171 else :
166172 alternatives .append ((encrypted_alternative ,
167173 "application/gpg-encrypted" ))
0 commit comments