@@ -124,7 +124,8 @@ struct MessageHeaders {
124
124
/// Headers that MUST NOT go into IMF header section.
125
125
///
126
126
/// 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.
128
129
pub hidden : Vec < Header > ,
129
130
}
130
131
@@ -560,24 +561,9 @@ impl<'a> MimeFactory<'a> {
560
561
Loaded :: Mdn { .. } => create_outgoing_rfc724_mid ( None , & self . from_addr ) ,
561
562
} ;
562
563
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) ;
581
567
582
568
// Reply headers as in <https://datatracker.ietf.org/doc/html/rfc5322#appendix-A.2>.
583
569
if !self . in_reply_to . is_empty ( ) {
@@ -783,29 +769,22 @@ impl<'a> MimeFactory<'a> {
783
769
)
784
770
. header ( ( "Subject" . to_string ( ) , "..." . to_string ( ) ) )
785
771
} 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 ( ) ) ;
799
780
800
781
// Store protected headers in the outer message.
801
782
let message = headers
802
783
. protected
803
784
. iter ( )
804
785
. fold ( message, |message, header| message. header ( header. clone ( ) ) ) ;
805
786
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 ? {
809
788
let protected: HashSet < Header > = HashSet :: from_iter ( headers. protected . into_iter ( ) ) ;
810
789
for h in headers. unprotected . split_off ( 0 ) {
811
790
if !protected. contains ( & h) {
@@ -2165,33 +2144,37 @@ mod tests {
2165
2144
let body = payload. next ( ) . unwrap ( ) ;
2166
2145
2167
2146
assert_eq ! ( outer. match_indices( "multipart/mixed" ) . count( ) , 1 ) ;
2147
+ assert_eq ! ( outer. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
2168
2148
assert_eq ! ( outer. match_indices( "Subject:" ) . count( ) , 1 ) ;
2169
2149
assert_eq ! ( outer. match_indices( "Autocrypt:" ) . count( ) , 1 ) ;
2170
2150
assert_eq ! ( outer. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
2171
2151
2172
2152
assert_eq ! ( inner. match_indices( "text/plain" ) . count( ) , 1 ) ;
2153
+ assert_eq ! ( inner. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
2173
2154
assert_eq ! ( inner. match_indices( "Chat-User-Avatar:" ) . count( ) , 1 ) ;
2174
2155
assert_eq ! ( inner. match_indices( "Subject:" ) . count( ) , 0 ) ;
2175
2156
2176
2157
assert_eq ! ( body. match_indices( "this is the text!" ) . count( ) , 1 ) ;
2177
2158
2178
2159
// if another message is sent, that one must not contain the avatar
2179
- // and no artificial multipart/mixed nesting
2180
2160
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 " ) ;
2182
2162
let outer = payload. next ( ) . unwrap ( ) ;
2163
+ let inner = payload. next ( ) . unwrap ( ) ;
2183
2164
let body = payload. next ( ) . unwrap ( ) ;
2184
2165
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 ) ;
2186
2168
assert_eq ! ( outer. match_indices( "Subject:" ) . count( ) , 1 ) ;
2187
2169
assert_eq ! ( outer. match_indices( "Autocrypt:" ) . count( ) , 1 ) ;
2188
- assert_eq ! ( outer. match_indices( "multipart/mixed" ) . count( ) , 0 ) ;
2189
2170
assert_eq ! ( outer. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
2190
2171
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
+
2191
2177
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 ) ;
2195
2178
2196
2179
Ok ( ( ) )
2197
2180
}
@@ -2223,6 +2206,7 @@ mod tests {
2223
2206
let part = payload. next ( ) . unwrap ( ) ;
2224
2207
assert_eq ! ( part. match_indices( "multipart/signed" ) . count( ) , 1 ) ;
2225
2208
assert_eq ! ( part. match_indices( "From:" ) . count( ) , 1 ) ;
2209
+ assert_eq ! ( part. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
2226
2210
assert_eq ! ( part. match_indices( "Subject:" ) . count( ) , 0 ) ;
2227
2211
assert_eq ! ( part. match_indices( "Autocrypt:" ) . count( ) , 1 ) ;
2228
2212
assert_eq ! ( part. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
@@ -2234,13 +2218,15 @@ mod tests {
2234
2218
1
2235
2219
) ;
2236
2220
assert_eq ! ( part. match_indices( "From:" ) . count( ) , 1 ) ;
2221
+ assert_eq ! ( part. match_indices( "Message-ID:" ) . count( ) , 0 ) ;
2237
2222
assert_eq ! ( part. match_indices( "Subject:" ) . count( ) , 1 ) ;
2238
2223
assert_eq ! ( part. match_indices( "Autocrypt:" ) . count( ) , 0 ) ;
2239
2224
assert_eq ! ( part. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
2240
2225
2241
2226
let part = payload. next ( ) . unwrap ( ) ;
2242
2227
assert_eq ! ( part. match_indices( "text/plain" ) . count( ) , 1 ) ;
2243
2228
assert_eq ! ( part. match_indices( "From:" ) . count( ) , 0 ) ;
2229
+ assert_eq ! ( part. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
2244
2230
assert_eq ! ( part. match_indices( "Chat-User-Avatar:" ) . count( ) , 1 ) ;
2245
2231
assert_eq ! ( part. match_indices( "Subject:" ) . count( ) , 0 ) ;
2246
2232
@@ -2261,31 +2247,38 @@ mod tests {
2261
2247
. is_some( ) ) ;
2262
2248
2263
2249
// if another message is sent, that one must not contain the avatar
2264
- // and no artificial multipart/mixed nesting
2265
2250
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 " ) ;
2267
2252
2268
2253
let part = payload. next ( ) . unwrap ( ) ;
2269
2254
assert_eq ! ( part. match_indices( "multipart/signed" ) . count( ) , 1 ) ;
2270
2255
assert_eq ! ( part. match_indices( "From:" ) . count( ) , 1 ) ;
2256
+ assert_eq ! ( part. match_indices( "Message-ID:" ) . count( ) , 1 ) ;
2271
2257
assert_eq ! ( part. match_indices( "Subject:" ) . count( ) , 0 ) ;
2272
2258
assert_eq ! ( part. match_indices( "Autocrypt:" ) . count( ) , 1 ) ;
2273
2259
assert_eq ! ( part. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
2274
2260
2275
2261
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
+ ) ;
2277
2267
assert_eq ! ( part. match_indices( "From:" ) . count( ) , 1 ) ;
2268
+ assert_eq ! ( part. match_indices( "Message-ID:" ) . count( ) , 0 ) ;
2278
2269
assert_eq ! ( part. match_indices( "Subject:" ) . count( ) , 1 ) ;
2279
2270
assert_eq ! ( part. match_indices( "Autocrypt:" ) . count( ) , 0 ) ;
2280
- assert_eq ! ( part. match_indices( "multipart/mixed" ) . count( ) , 0 ) ;
2281
2271
assert_eq ! ( part. match_indices( "Chat-User-Avatar:" ) . count( ) , 0 ) ;
2282
2272
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
+
2283
2280
let body = payload. next ( ) . unwrap ( ) ;
2284
2281
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 ) ;
2289
2282
2290
2283
bob. recv_msg ( & sent_msg) . await ;
2291
2284
let alice_contact = Contact :: get_by_id ( & bob. ctx , alice_id) . await . unwrap ( ) ;
0 commit comments