mirror of
https://github.com/chatmail/core.git
synced 2026-04-21 15:36:30 +03:00
fix: Take the last valid Autocrypt header (#7167)
DKIM-Signatures apply to the last headers, so start from the last header and take a valid one, i.e. skip headers having unknown critical attributes, etc. Though this means that Autocrypt header must be "oversigned" to guarantee that a not DKIM-signed header isn't taken, still start from the last header for consistency with processing other headers. This isn't a security issue anyway.
This commit is contained in:
@@ -351,7 +351,7 @@ impl MimeMessage {
|
||||
|
||||
let incoming = !context.is_self_addr(&from.addr).await?;
|
||||
|
||||
let mut aheader_value: Option<String> = 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();
|
||||
|
||||
Reference in New Issue
Block a user