Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
lacre:ongoing [2024/04/19 13:02] – Research: avoiding... - multipart messages pfmlacre:ongoing [2024/07/12 17:17] (current) – cont: Research: Thunderbird's handling pfm
Line 1: Line 1:
 ====== Lacre - ongoing work ====== ====== Lacre - ongoing work ======
  
-  - "Great renaming" --- our fork is ours, let's reflect it with unifying the names used all over the code (see [[lacreissue>81|issue 81]]).+  - [[lacreissue>153|Avoid message transformation]] 
 +  [[lacreissue>151|Upgrade SQLAlchemy to 2.0]] 
 +  - [[lacreissue>150|Perform database operations on transactions]]
  
 ===== Reliability improvements ===== ===== Reliability improvements =====
Line 18: Line 20:
  
 ''BytesHeaderParser'' and its string counterpart let us only parse the headers and keep original message body in memory. The drawback is that we can't process multipart messages as sequences of MIME entities, which we need for one of the Lacre's modes of operation. (There are two: PGP/MIME with whole body encrypted and PGP/Inline with each part of multipart message encrypted separately.) We could use ''BytesHeaderParser'' with PGP/MIME only, because a multipart message would be impossible to handle in PGP/Inline mode. ''BytesHeaderParser'' and its string counterpart let us only parse the headers and keep original message body in memory. The drawback is that we can't process multipart messages as sequences of MIME entities, which we need for one of the Lacre's modes of operation. (There are two: PGP/MIME with whole body encrypted and PGP/Inline with each part of multipart message encrypted separately.) We could use ''BytesHeaderParser'' with PGP/MIME only, because a multipart message would be impossible to handle in PGP/Inline mode.
 +
 +===== Research: avoiding message transformation (part 2) =====
 +
 +It turns out that we can avoid //some// of the transformations:
 +
 +  * For messages in cleartext, already encrypted and those processed in PGP/MIME mode we could just take original message content ([[https://aiosmtpd.aio-libs.org/en/latest/concepts.html#Envelope.original_content|Envelope.original_content]]) and process it. Thus we'd avoid using [[https://docs.python.org/3/library/email.contentmanager.html#module-email.contentmanager|email.contentmanager]], which is the component responsible for decoding MIME entities.
 +  * Messages processed in PGP/Inline mode would risk being transformed before encryption.
 +
 +To achieve that, we'd need to adjust the flow and:
 +
 +  - Work with a plain ''Envelope'' initially to identify identities and prepare for encryption.
 +  - We could use header-only parser mentioned above during delivery planning (''lacre.core'', function ''delivery_plan'').
 +  - Finally, if the message is known to be processed in PGP/Inline mode, we could load each MIME entity's body and process it. (Without ContentManager //if possible//.)
 +
 +===== Research: Thunderbird's handling of OpenPGP-encrypted messages =====
 +
 +Turns out when Thunderbird is expected to send a plain text message (something that would usually become a ''text/plain'' MIME entity accompanied by a bunch of headers), it does the following:
 +
 +  * It creates a ''multipart/encrypted'' MIME entity (RFC 4880 and 3156 compliant);
 +  * creates a ''multipart/mixed'' MIME entity;
 +  * populates its contents;
 +  * encrypts it and puts in the MIME entity from step 1.
 +
 +Populating the contents depends on the mode:
 +
 +  * If ''Subject:'' is encrypted too, original ''Subject:'' is replaced with the string ''...''.
 +  * If the user chooses to sign the message, their public key is included in the ''multipart/mixed'' entity.
 +  * Actual message body is included as Base 64-encoded MIME part of the ''multipart/mixed'' entity.
 +
 +Unfortunately we need to compose new MIME entity for every PGP/MIME-encrypted message, so we need to load contents of each part. To avoid transformation we could switch from ''get_content()'' to ''get_payload(decode=False)'', so we'd get strings with raw MIME entity payloads, giving us a chance to populate ''multipart/mixed'' in step 2 above with non-transformed payloads.
 +