diff --git a/src/mimeparser.rs b/src/mimeparser.rs index cae9357ca..ce4d10459 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -351,7 +351,7 @@ impl MimeMessage { let incoming = !context.is_self_addr(&from.addr).await?; - let mut aheader_value: Option = mail.headers.get_header_value(HeaderDef::Autocrypt); + let mut aheader_values = mail.headers.get_all_values(HeaderDef::Autocrypt.into()); let mail_raw; // Memory location for a possible decrypted message. let decrypted_msg; // Decrypted signed OpenPGP message. @@ -378,11 +378,11 @@ impl MimeMessage { timestamp_rcvd, ); - if let Some(protected_aheader_value) = decrypted_mail + let protected_aheader_values = decrypted_mail .headers - .get_header_value(HeaderDef::Autocrypt) - { - aheader_value = Some(protected_aheader_value); + .get_all_values(HeaderDef::Autocrypt.into()); + if !protected_aheader_values.is_empty() { + aheader_values = protected_aheader_values; } (Ok(decrypted_mail), true) @@ -400,26 +400,27 @@ impl MimeMessage { } }; - let autocrypt_header = if !incoming { - None - } else if let Some(aheader_value) = aheader_value { - match Aheader::from_str(&aheader_value) { - Ok(header) if addr_cmp(&header.addr, &from.addr) => Some(header), - Ok(header) => { - warn!( - context, - "Autocrypt header address {:?} is not {:?}.", header.addr, from.addr - ); - None - } - Err(err) => { - warn!(context, "Failed to parse Autocrypt header: {:#}.", err); - None - } + let mut autocrypt_header = None; + if incoming { + // See `get_all_addresses_from_header()` for why we take the last valid header. + for val in aheader_values.iter().rev() { + autocrypt_header = match Aheader::from_str(val) { + Ok(header) if addr_cmp(&header.addr, &from.addr) => Some(header), + Ok(header) => { + warn!( + context, + "Autocrypt header address {:?} is not {:?}.", header.addr, from.addr + ); + continue; + } + Err(err) => { + warn!(context, "Failed to parse Autocrypt header: {:#}.", err); + continue; + } + }; + break; } - } else { - None - }; + } let autocrypt_fingerprint = if let Some(autocrypt_header) = &autocrypt_header { let fingerprint = autocrypt_header.public_key.dc_fingerprint().hex(); diff --git a/src/mimeparser/mimeparser_tests.rs b/src/mimeparser/mimeparser_tests.rs index 73ea93b21..13f8702b7 100644 --- a/src/mimeparser/mimeparser_tests.rs +++ b/src/mimeparser/mimeparser_tests.rs @@ -1990,6 +1990,27 @@ async fn test_chat_edit_imf_header() -> Result<()> { Ok(()) } +/// Tests that the last valid Autocrypt header is taken: +/// - The 3rd header is skipped because of the unknown critical attribute. +/// - The 2nd header is taken despite it has an unknown non-critical attribute. +/// - The 1st header shouldn't be looked at. +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_multiple_autocrypt_hdrs() -> Result<()> { + let mut tcm = TestContextManager::new(); + let bob = &tcm.bob().await; + let msg_id = receive_imf( + bob, + include_bytes!("../../test-data/message/thunderbird_with_multiple_autocrypts.eml"), + false, + ) + .await? + .unwrap() + .msg_ids[0]; + let msg = Message::load_from_db(bob, msg_id).await?; + assert!(msg.get_showpadlock()); + Ok(()) +} + /// Tests that timestamp of signed but not encrypted message is protected. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_protected_date() -> Result<()> { diff --git a/test-data/message/thunderbird_with_multiple_autocrypts.eml b/test-data/message/thunderbird_with_multiple_autocrypts.eml new file mode 100644 index 000000000..7683a6a9d --- /dev/null +++ b/test-data/message/thunderbird_with_multiple_autocrypts.eml @@ -0,0 +1,134 @@ +Message-ID: <0bb9ffe1-2596-d997-95b4-1fef8cc4808e@example.org> +Date: Thu, 24 Nov 2022 20:05:57 +0100 +MIME-Version: 1.0 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 + Thunderbird/102.4.2 +From: Alice +To: bob@example.net +Content-Language: en-US +Autocrypt: addr=alice@example.org; + keydata=xsBNBF4wx1cBCADOwLS/xCd8iKDWUsyTfVzWby+ZGKPpamPTvdj0GFgnf0B1EBaA5//PjA + zbK5iKio6QNEmZagzJPkXPByJcAIRUm0T16tqDtCvxm+H93YEXpHi/XWOeJw9kohATSqUtsRO0pFJe + DvPiMTmQrEmHYoWDSQBfCrowZdvnMAlbJ9JjYOngcMeTxc0jxmPs5s17yFC+1OWu4fwWCyUM3wy1Jz + dKTcDWryrSkvmgFdUqJ7pJDk1HFTt+x9tvQlK3un9BXiRwv0u0zDSuI8eDH/dRLA4UL9Pq6vmJmBam + e1BPsE1PA7VzeTSJR2ooJXMT6o2AmH8PPUfRkv3OiWuh7LM5FSpHABEBAAHNETxib2JAZXhhbXBsZS + 5uZXQ+wsCOBBABCAA4BQJo0CE8FiEEzMtaqfbhFByUMWXx2xixjLz3BIcCGwMCHgAECwkIBwYVCAkK + CwIDFgIBAScCGQEACgkQ2xixjLz3BIciNwgAnPIoh9FWEm5p/SH/KqHfkpctf/47WlNxxFTFGpda/4 + zKpNgAQmMJdZ0UXeBfYn8nY7SWO5Yv/mpQ4eqwvu5meX0X+Vl9XjUcse8tbdSioC+CSwymFdmucrKo + A3gjRXh6r/HxcoWRtJc1+yL8B6gvbToKL7r71yeDedTs/fvFk0cZgpVBs9YJZaBq6OwSaZcWY4McSI + lVysb6Hv02MoLJidP8AOza+A2wRQQ0Xe9mxhP8sZnsnAhQBpD4rN619tXuwWLl+idwAXFxNGamURaz + l1LFDN8AgSM0pEgBBT4aHdRWoWXluVs6eVOt2lQza3/rcUU08RYIhdYj9EkTTDe4kM7ATQReMMdXAQ + gAogeBLbIjaeJII3W2pxsu+SEusQkJVykbGYDtqyXV+XBZisY4GE0kTawK5mqSh+rDqquCxDgYWBRT + nGZwEKohnj2NG75pjfyVPhYMUdJt7+Ya1oiFvZlgrrOj1btjevq53yFtQolMN+X2oS8mlf9jSzIyPC + eDxJk1N1gxaAATg3ByAyB1Td0wDdFPp48ni8qzfyGZeYicvJlx74YnOaja2lnI/y+I9LsmmqiOgI8H + cbmH1od5qSnVjhcpBoTEA15YLIEkSE3C00Q5USlDS3EVg/IOu3FXnLl7v0hQ/jXyv88eycfpSfFcbM + Hot9VtJ4TIPIoSX7DQ+uU2SXJKiZNkVQARAQABwsB2BBgBCAAgBQJo0CE8AhsMFiEEzMtaqfbhFByU + MWXx2xixjLz3BIcACgkQ2xixjLz3BIcYpAf+Jpa5wK0dzwcoFOiie6gRBPooC33LsUA7AK5qJ1NplF + m9Yax3JPSGPmLcN1NbsJfDIlxnfnvqHBQgBQU87OCPynnATkXY/OXQzOFd8UODKetFYyE3kyVSI69L + Dx2YmhafQcpzQ2o/keDynb6VznLEOja7kPyRhzFml/HBdoY5MILo2BKrrMWI7vopRFBbKEIjvdxJAo + Yx97oTVsTwlhOIcGKo3dTPBsQfbk760BM1V1bdB/Us9Vi4l/yKX59Pbt9kqYP524HNPQOtUAYG5qUP + r6gG6EFSt7XE5PbZ621X0yH5D+KJt8F5d4/bLRLNdzuyZP/x9rKq1MUUjRxNes2xSg== +Autocrypt: addr=alice@example.org; _valid=yes; keydata= + xjMEXlh13RYJKwYBBAHaRw8BAQdAzfVIAleCXMJrq8VeLlEVof6ITCviMktKjmcBKAu4m5DN + GUFsaWNlIDxhbGljZUBleGFtcGxlLm9yZz7CkAQTFggAOBYhBC5vossjtTLXKGNLWGSwj2Gp + 7ZRDBQJeWHXdAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEGSwj2Gp7ZRDE3oA/i4M + CyDMTsjWqDZoQwX/A/GoTO2/V0wKPhjJJy/8m2pMAPkBjOnGOtx2SZpQvJGTa9h804RY6iDr + RuI8A/8tEEXAA844BF5Ydd0SCisGAQQBl1UBBQEBB0AG7cjWy2SFAU8KnltlubVW67rFiyfp + 01JrRe6Xqy22HQMBCAfCeAQYFggAIBYhBC5vossjtTLXKGNLWGSwj2Gp7ZRDBQJeWHXdAhsM + AAoJEGSwj2Gp7ZRDLo8BAObE8GnsGVwKzNqCvHeWgJsqhjS3C6gvSlV3tEm9XmF6AQDXucIy + VfoBwoyMh2h6cSn/ATn5QJb35pgo+ivp3jsMAg== +Autocrypt: addr=alice@example.org; valid=no; + keydata=xsBNBF4wx1cBCADOwLS/xCd8iKDWUsyTfVzWby+ZGKPpamPTvdj0GFgnf0B1EBaA5//PjA + zbK5iKio6QNEmZagzJPkXPByJcAIRUm0T16tqDtCvxm+H93YEXpHi/XWOeJw9kohATSqUtsRO0pFJe + DvPiMTmQrEmHYoWDSQBfCrowZdvnMAlbJ9JjYOngcMeTxc0jxmPs5s17yFC+1OWu4fwWCyUM3wy1Jz + dKTcDWryrSkvmgFdUqJ7pJDk1HFTt+x9tvQlK3un9BXiRwv0u0zDSuI8eDH/dRLA4UL9Pq6vmJmBam + e1BPsE1PA7VzeTSJR2ooJXMT6o2AmH8PPUfRkv3OiWuh7LM5FSpHABEBAAHNETxib2JAZXhhbXBsZS + 5uZXQ+wsCOBBABCAA4BQJo0CE8FiEEzMtaqfbhFByUMWXx2xixjLz3BIcCGwMCHgAECwkIBwYVCAkK + CwIDFgIBAScCGQEACgkQ2xixjLz3BIciNwgAnPIoh9FWEm5p/SH/KqHfkpctf/47WlNxxFTFGpda/4 + zKpNgAQmMJdZ0UXeBfYn8nY7SWO5Yv/mpQ4eqwvu5meX0X+Vl9XjUcse8tbdSioC+CSwymFdmucrKo + A3gjRXh6r/HxcoWRtJc1+yL8B6gvbToKL7r71yeDedTs/fvFk0cZgpVBs9YJZaBq6OwSaZcWY4McSI + lVysb6Hv02MoLJidP8AOza+A2wRQQ0Xe9mxhP8sZnsnAhQBpD4rN619tXuwWLl+idwAXFxNGamURaz + l1LFDN8AgSM0pEgBBT4aHdRWoWXluVs6eVOt2lQza3/rcUU08RYIhdYj9EkTTDe4kM7ATQReMMdXAQ + gAogeBLbIjaeJII3W2pxsu+SEusQkJVykbGYDtqyXV+XBZisY4GE0kTawK5mqSh+rDqquCxDgYWBRT + nGZwEKohnj2NG75pjfyVPhYMUdJt7+Ya1oiFvZlgrrOj1btjevq53yFtQolMN+X2oS8mlf9jSzIyPC + eDxJk1N1gxaAATg3ByAyB1Td0wDdFPp48ni8qzfyGZeYicvJlx74YnOaja2lnI/y+I9LsmmqiOgI8H + cbmH1od5qSnVjhcpBoTEA15YLIEkSE3C00Q5USlDS3EVg/IOu3FXnLl7v0hQ/jXyv88eycfpSfFcbM + Hot9VtJ4TIPIoSX7DQ+uU2SXJKiZNkVQARAQABwsB2BBgBCAAgBQJo0CE8AhsMFiEEzMtaqfbhFByU + MWXx2xixjLz3BIcACgkQ2xixjLz3BIcYpAf+Jpa5wK0dzwcoFOiie6gRBPooC33LsUA7AK5qJ1NplF + m9Yax3JPSGPmLcN1NbsJfDIlxnfnvqHBQgBQU87OCPynnATkXY/OXQzOFd8UODKetFYyE3kyVSI69L + Dx2YmhafQcpzQ2o/keDynb6VznLEOja7kPyRhzFml/HBdoY5MILo2BKrrMWI7vopRFBbKEIjvdxJAo + Yx97oTVsTwlhOIcGKo3dTPBsQfbk760BM1V1bdB/Us9Vi4l/yKX59Pbt9kqYP524HNPQOtUAYG5qUP + r6gG6EFSt7XE5PbZ621X0yH5D+KJt8F5d4/bLRLNdzuyZP/x9rKq1MUUjRxNes2xSg== +Subject: ... +Content-Type: multipart/encrypted; + protocol="application/pgp-encrypted"; + boundary="------------EOdOT2kJUL5hgCilmIhYyVZg" + +This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156) +--------------EOdOT2kJUL5hgCilmIhYyVZg +Content-Type: application/pgp-encrypted +Content-Description: PGP/MIME version identification + +Version: 1 + +--------------EOdOT2kJUL5hgCilmIhYyVZg +Content-Type: application/octet-stream; name="encrypted.asc" +Content-Description: OpenPGP encrypted message +Content-Disposition: inline; filename="encrypted.asc" + +-----BEGIN PGP MESSAGE----- + +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 +oO4vW9/JEmFUqLyQmWnoLJHX3IKtWa9CPvE= +=OA6b +-----END PGP MESSAGE----- + +--------------EOdOT2kJUL5hgCilmIhYyVZg--