@@ -124,7 +124,8 @@ struct MessageHeaders {
124124 /// Headers that MUST NOT go into IMF header section.
125125 ///
126126 /// These are large headers which may hit the header section size limit on the server, such as
127- /// Chat-User-Avatar with a base64-encoded image inside.
127+ /// Chat-User-Avatar with a base64-encoded image inside. Also there are headers duplicated here
128+ /// that servers mess up with in the IMF header section, like Message-ID.
128129 pub hidden : Vec < Header > ,
129130}
130131
@@ -560,24 +561,9 @@ impl<'a> MimeFactory<'a> {
560561 Loaded :: Mdn { .. } => create_outgoing_rfc724_mid ( None , & self . from_addr ) ,
561562 } ;
562563 let rfc724_mid_headervalue = render_rfc724_mid ( & rfc724_mid) ;
563-
564- // Amazon's SMTP servers change the `Message-ID`, just as Outlook's SMTP servers do.
565- // Outlook's servers add an `X-Microsoft-Original-Message-ID` header with the original `Message-ID`,
566- // and when downloading messages we look for this header in order to correctly identify
567- // messages.
568- // Amazon's servers do not add such a header, so we just add it ourselves.
569- if let Some ( server) = context. get_config ( Config :: ConfiguredSendServer ) . await ? {
570- if server. ends_with ( ".amazonaws.com" ) {
571- headers. unprotected . push ( Header :: new (
572- "X-Microsoft-Original-Message-ID" . into ( ) ,
573- rfc724_mid_headervalue. clone ( ) ,
574- ) )
575- }
576- }
577-
578- headers
579- . unprotected
580- . push ( Header :: new ( "Message-ID" . into ( ) , rfc724_mid_headervalue) ) ;
564+ let rfc724_mid_header = Header :: new ( "Message-ID" . into ( ) , rfc724_mid_headervalue) ;
565+ headers. unprotected . push ( rfc724_mid_header. clone ( ) ) ;
566+ headers. hidden . push ( rfc724_mid_header) ;
581567
582568 // Reply headers as in <https://datatracker.ietf.org/doc/html/rfc5322#appendix-A.2>.
583569 if !self . in_reply_to . is_empty ( ) {
@@ -783,29 +769,22 @@ impl<'a> MimeFactory<'a> {
783769 )
784770 . header ( ( "Subject" . to_string ( ) , "..." . to_string ( ) ) )
785771 } else {
786- let message = if headers. hidden . is_empty ( ) {
787- message
788- } else {
789- // Store hidden headers in the inner unencrypted message.
790- let message = headers
791- . hidden
792- . into_iter ( )
793- . fold ( message, |message, header| message. header ( header) ) ;
794-
795- PartBuilder :: new ( )
796- . message_type ( MimeMultipartType :: Mixed )
797- . child ( message. build ( ) )
798- } ;
772+ // Store hidden headers in the inner unencrypted message.
773+ let message = headers
774+ . hidden
775+ . into_iter ( )
776+ . fold ( message, |message, header| message. header ( header) ) ;
777+ let message = PartBuilder :: new ( )
778+ . message_type ( MimeMultipartType :: Mixed )
779+ . child ( message. build ( ) ) ;
799780
800781 // Store protected headers in the outer message.
801782 let message = headers
802783 . protected
803784 . iter ( )
804785 . fold ( message, |message, header| message. header ( header. clone ( ) ) ) ;
805786
806- if self . should_skip_autocrypt ( )
807- || !context. get_config_bool ( Config :: SignUnencrypted ) . await ?
808- {
787+ if skip_autocrypt || !context. get_config_bool ( Config :: SignUnencrypted ) . await ? {
809788 let protected: HashSet < Header > = HashSet :: from_iter ( headers. protected . into_iter ( ) ) ;
810789 for h in headers. unprotected . split_off ( 0 ) {
811790 if !protected. contains ( & h) {
@@ -2165,33 +2144,37 @@ mod tests {
21652144 let body = payload. next ( ) . unwrap ( ) ;
21662145
21672146 assert_eq ! ( outer. match_indices( "multipart/mixed" ) . count( ) , 1 ) ;
2147+ assert_eq ! ( outer. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
21682148 assert_eq ! ( outer. match_indices( "Subject:" ) . count( ) , 1 ) ;
21692149 assert_eq ! ( outer. match_indices( "Autocrypt:" ) . count( ) , 1 ) ;
21702150 assert_eq ! ( outer. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
21712151
21722152 assert_eq ! ( inner. match_indices( "text/plain" ) . count( ) , 1 ) ;
2153+ assert_eq ! ( inner. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
21732154 assert_eq ! ( inner. match_indices( "Chat-User-Avatar:" ) . count( ) , 1 ) ;
21742155 assert_eq ! ( inner. match_indices( "Subject:" ) . count( ) , 0 ) ;
21752156
21762157 assert_eq ! ( body. match_indices( "this is the text!" ) . count( ) , 1 ) ;
21772158
21782159 // if another message is sent, that one must not contain the avatar
2179- // and no artificial multipart/mixed nesting
21802160 let sent_msg = t. send_msg ( chat. id , & mut msg) . await ;
2181- let mut payload = sent_msg. payload ( ) . splitn ( 2 , "\r \n \r \n " ) ;
2161+ let mut payload = sent_msg. payload ( ) . splitn ( 3 , "\r \n \r \n " ) ;
21822162 let outer = payload. next ( ) . unwrap ( ) ;
2163+ let inner = payload. next ( ) . unwrap ( ) ;
21832164 let body = payload. next ( ) . unwrap ( ) ;
21842165
2185- assert_eq ! ( outer. match_indices( "text/plain" ) . count( ) , 1 ) ;
2166+ assert_eq ! ( outer. match_indices( "multipart/mixed" ) . count( ) , 1 ) ;
2167+ assert_eq ! ( outer. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
21862168 assert_eq ! ( outer. match_indices( "Subject:" ) . count( ) , 1 ) ;
21872169 assert_eq ! ( outer. match_indices( "Autocrypt:" ) . count( ) , 1 ) ;
2188- assert_eq ! ( outer. match_indices( "multipart/mixed" ) . count( ) , 0 ) ;
21892170 assert_eq ! ( outer. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
21902171
2172+ assert_eq ! ( inner. match_indices( "text/plain" ) . count( ) , 1 ) ;
2173+ assert_eq ! ( inner. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
2174+ assert_eq ! ( inner. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
2175+ assert_eq ! ( inner. match_indices( "Subject:" ) . count( ) , 0 ) ;
2176+
21912177 assert_eq ! ( body. match_indices( "this is the text!" ) . count( ) , 1 ) ;
2192- assert_eq ! ( body. match_indices( "text/plain" ) . count( ) , 0 ) ;
2193- assert_eq ! ( body. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
2194- assert_eq ! ( body. match_indices( "Subject:" ) . count( ) , 0 ) ;
21952178
21962179 Ok ( ( ) )
21972180 }
@@ -2223,6 +2206,7 @@ mod tests {
22232206 let part = payload. next ( ) . unwrap ( ) ;
22242207 assert_eq ! ( part. match_indices( "multipart/signed" ) . count( ) , 1 ) ;
22252208 assert_eq ! ( part. match_indices( "From:" ) . count( ) , 1 ) ;
2209+ assert_eq ! ( part. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
22262210 assert_eq ! ( part. match_indices( "Subject:" ) . count( ) , 0 ) ;
22272211 assert_eq ! ( part. match_indices( "Autocrypt:" ) . count( ) , 1 ) ;
22282212 assert_eq ! ( part. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
@@ -2234,13 +2218,15 @@ mod tests {
22342218 1
22352219 ) ;
22362220 assert_eq ! ( part. match_indices( "From:" ) . count( ) , 1 ) ;
2221+ assert_eq ! ( part. match_indices( "Message-ID:" ) . count( ) , 0 ) ;
22372222 assert_eq ! ( part. match_indices( "Subject:" ) . count( ) , 1 ) ;
22382223 assert_eq ! ( part. match_indices( "Autocrypt:" ) . count( ) , 0 ) ;
22392224 assert_eq ! ( part. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
22402225
22412226 let part = payload. next ( ) . unwrap ( ) ;
22422227 assert_eq ! ( part. match_indices( "text/plain" ) . count( ) , 1 ) ;
22432228 assert_eq ! ( part. match_indices( "From:" ) . count( ) , 0 ) ;
2229+ assert_eq ! ( part. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
22442230 assert_eq ! ( part. match_indices( "Chat-User-Avatar:" ) . count( ) , 1 ) ;
22452231 assert_eq ! ( part. match_indices( "Subject:" ) . count( ) , 0 ) ;
22462232
@@ -2261,31 +2247,38 @@ mod tests {
22612247 . is_some( ) ) ;
22622248
22632249 // if another message is sent, that one must not contain the avatar
2264- // and no artificial multipart/mixed nesting
22652250 let sent_msg = t. send_msg ( chat. id , & mut msg) . await ;
2266- let mut payload = sent_msg. payload ( ) . splitn ( 3 , "\r \n \r \n " ) ;
2251+ let mut payload = sent_msg. payload ( ) . splitn ( 4 , "\r \n \r \n " ) ;
22672252
22682253 let part = payload. next ( ) . unwrap ( ) ;
22692254 assert_eq ! ( part. match_indices( "multipart/signed" ) . count( ) , 1 ) ;
22702255 assert_eq ! ( part. match_indices( "From:" ) . count( ) , 1 ) ;
2256+ assert_eq ! ( part. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
22712257 assert_eq ! ( part. match_indices( "Subject:" ) . count( ) , 0 ) ;
22722258 assert_eq ! ( part. match_indices( "Autocrypt:" ) . count( ) , 1 ) ;
22732259 assert_eq ! ( part. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
22742260
22752261 let part = payload. next ( ) . unwrap ( ) ;
2276- assert_eq ! ( part. match_indices( "text/plain" ) . count( ) , 1 ) ;
2262+ assert_eq ! (
2263+ part. match_indices( "multipart/mixed; protected-headers=\" v1\" " )
2264+ . count( ) ,
2265+ 1
2266+ ) ;
22772267 assert_eq ! ( part. match_indices( "From:" ) . count( ) , 1 ) ;
2268+ assert_eq ! ( part. match_indices( "Message-ID:" ) . count( ) , 0 ) ;
22782269 assert_eq ! ( part. match_indices( "Subject:" ) . count( ) , 1 ) ;
22792270 assert_eq ! ( part. match_indices( "Autocrypt:" ) . count( ) , 0 ) ;
2280- assert_eq ! ( part. match_indices( "multipart/mixed" ) . count( ) , 0 ) ;
22812271 assert_eq ! ( part. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
22822272
2273+ let part = payload. next ( ) . unwrap ( ) ;
2274+ assert_eq ! ( part. match_indices( "text/plain" ) . count( ) , 1 ) ;
2275+ assert_eq ! ( body. match_indices( "From:" ) . count( ) , 0 ) ;
2276+ assert_eq ! ( part. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
2277+ assert_eq ! ( part. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
2278+ assert_eq ! ( part. match_indices( "Subject:" ) . count( ) , 0 ) ;
2279+
22832280 let body = payload. next ( ) . unwrap ( ) ;
22842281 assert_eq ! ( body. match_indices( "this is the text!" ) . count( ) , 1 ) ;
2285- assert_eq ! ( body. match_indices( "text/plain" ) . count( ) , 0 ) ;
2286- assert_eq ! ( body. match_indices( "From:" ) . count( ) , 0 ) ;
2287- assert_eq ! ( body. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
2288- assert_eq ! ( body. match_indices( "Subject:" ) . count( ) , 0 ) ;
22892282
22902283 bob. recv_msg ( & sent_msg) . await ;
22912284 let alice_contact = Contact :: get_by_id ( & bob. ctx , alice_id) . await . unwrap ( ) ;
0 commit comments