@@ -246,6 +246,7 @@ impl MimeMessage {
246
246
MimeMessage :: merge_headers (
247
247
context,
248
248
& mut headers,
249
+ & mut headers_removed,
249
250
& mut recipients,
250
251
& mut past_members,
251
252
& mut from,
@@ -273,6 +274,7 @@ impl MimeMessage {
273
274
MimeMessage :: merge_headers (
274
275
context,
275
276
& mut headers,
277
+ & mut headers_removed,
276
278
& mut recipients,
277
279
& mut past_members,
278
280
& mut from,
@@ -446,26 +448,11 @@ impl MimeMessage {
446
448
} ) ;
447
449
if let ( Ok ( mail) , true ) = ( mail, is_encrypted) {
448
450
if !signatures. is_empty ( ) {
449
- // Remove unsigned opportunistically protected headers from messages considered
450
- // Autocrypt-encrypted / displayed with padlock.
451
- // For "Subject" see <https://github.com/deltachat/deltachat-core-rust/issues/1790>.
452
- for h in [
453
- HeaderDef :: Subject ,
454
- HeaderDef :: ChatGroupId ,
455
- HeaderDef :: ChatGroupName ,
456
- HeaderDef :: ChatGroupNameChanged ,
457
- HeaderDef :: ChatGroupNameTimestamp ,
458
- HeaderDef :: ChatGroupAvatar ,
459
- HeaderDef :: ChatGroupMemberRemoved ,
460
- HeaderDef :: ChatGroupMemberAdded ,
461
- HeaderDef :: ChatGroupMemberTimestamps ,
462
- HeaderDef :: ChatGroupPastMembers ,
463
- HeaderDef :: ChatDelete ,
464
- HeaderDef :: ChatEdit ,
465
- HeaderDef :: ChatUserAvatar ,
466
- ] {
467
- remove_header ( & mut headers, h. get_headername ( ) , & mut headers_removed) ;
468
- }
451
+ // Unsigned "Subject" mustn't be prepended to messages shown as encrypted
452
+ // (<https://github.com/deltachat/deltachat-core-rust/issues/1790>).
453
+ // Other headers are removed by `MimeMessage::merge_headers()` except for "List-ID".
454
+ remove_header ( & mut headers, "subject" , & mut headers_removed) ;
455
+ remove_header ( & mut headers, "list-id" , & mut headers_removed) ;
469
456
}
470
457
471
458
// let known protected headers from the decrypted
@@ -478,6 +465,7 @@ impl MimeMessage {
478
465
MimeMessage :: merge_headers (
479
466
context,
480
467
& mut headers,
468
+ & mut headers_removed,
481
469
& mut recipients,
482
470
& mut past_members,
483
471
& mut inner_from,
@@ -1558,19 +1546,28 @@ impl MimeMessage {
1558
1546
fn merge_headers (
1559
1547
context : & Context ,
1560
1548
headers : & mut HashMap < String , String > ,
1549
+ headers_removed : & mut HashSet < String > ,
1561
1550
recipients : & mut Vec < SingleInfo > ,
1562
1551
past_members : & mut Vec < SingleInfo > ,
1563
1552
from : & mut Option < SingleInfo > ,
1564
1553
list_post : & mut Option < String > ,
1565
1554
chat_disposition_notification_to : & mut Option < SingleInfo > ,
1566
1555
fields : & [ mailparse:: MailHeader < ' _ > ] ,
1567
1556
) {
1557
+ // There are known cases when Subject and List-ID only appear in the IMF section of
1558
+ // signed-only messages. Such messages are shown as unencrypted anyway.
1559
+ headers. retain ( |k, _| {
1560
+ !is_protected ( k) || k == "subject" || k == "list-id" || {
1561
+ headers_removed. insert ( k. to_string ( ) ) ;
1562
+ false
1563
+ }
1564
+ } ) ;
1568
1565
for field in fields {
1569
1566
// lowercasing all headers is technically not correct, but makes things work better
1570
1567
let key = field. get_key ( ) . to_lowercase ( ) ;
1571
- if !headers . contains_key ( & key ) || // key already exists, only overwrite known types (protected headers)
1572
- is_known ( & key ) || key . starts_with ( "chat-" )
1573
- {
1568
+ // Don't overwrite unprotected headers, but overwrite protected ones because DKIM
1569
+ // signature applies to the last headers.
1570
+ if !headers . contains_key ( & key ) || is_protected ( & key ) {
1574
1571
if key == HeaderDef :: ChatDispositionNotificationTo . get_headername ( ) {
1575
1572
match addrparse_header ( field) {
1576
1573
Ok ( addrlist) => {
@@ -2011,24 +2008,27 @@ pub(crate) fn parse_message_id(ids: &str) -> Result<String> {
2011
2008
2012
2009
/// Returns true if the header overwrites outer header
2013
2010
/// when it comes from protected headers.
2014
- fn is_known ( key : & str ) -> bool {
2015
- matches ! (
2016
- key,
2017
- "return-path"
2018
- | "date"
2019
- | "from"
2020
- | "sender"
2021
- | "reply-to"
2022
- | "to"
2023
- | "cc"
2024
- | "bcc"
2025
- | "message-id"
2026
- | "in-reply-to"
2027
- | "references"
2028
- | "subject"
2029
- | "secure-join"
2030
- | "list-id"
2031
- )
2011
+ fn is_protected ( key : & str ) -> bool {
2012
+ key. starts_with ( "chat-" )
2013
+ || matches ! (
2014
+ key,
2015
+ "return-path"
2016
+ | "auto-submitted"
2017
+ | "autocrypt-setup-message"
2018
+ | "date"
2019
+ | "from"
2020
+ | "sender"
2021
+ | "reply-to"
2022
+ | "to"
2023
+ | "cc"
2024
+ | "bcc"
2025
+ | "message-id"
2026
+ | "in-reply-to"
2027
+ | "references"
2028
+ | "subject"
2029
+ | "secure-join"
2030
+ | "list-id"
2031
+ )
2032
2032
}
2033
2033
2034
2034
/// Returns if the header is hidden and must be ignored in the IMF section.
0 commit comments