mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
fix: always prefer the last header
Headers are normally added at the top of the message, e.g. when forwarding new `Received` headers are added at the top. When headers are protected with DKIM-Signature and oversigning is not used, forged headers may be added on top so headers from the top are generally less trustworthy. This is tested with `test_take_last_header`, but so far last header was only preferred for known headers. This change extends preference of the last header to all headers.
This commit is contained in:
@@ -1568,20 +1568,16 @@ impl MimeMessage {
|
||||
for field in fields {
|
||||
// lowercasing all headers is technically not correct, but makes things work better
|
||||
let key = field.get_key().to_lowercase();
|
||||
if !headers.contains_key(&key) || // key already exists, only overwrite known types (protected headers)
|
||||
is_known(&key) || key.starts_with("chat-")
|
||||
{
|
||||
if key == HeaderDef::ChatDispositionNotificationTo.get_headername() {
|
||||
match addrparse_header(field) {
|
||||
Ok(addrlist) => {
|
||||
*chat_disposition_notification_to = addrlist.extract_single_info();
|
||||
}
|
||||
Err(e) => warn!(context, "Could not read {} address: {}", key, e),
|
||||
if key == HeaderDef::ChatDispositionNotificationTo.get_headername() {
|
||||
match addrparse_header(field) {
|
||||
Ok(addrlist) => {
|
||||
*chat_disposition_notification_to = addrlist.extract_single_info();
|
||||
}
|
||||
} else {
|
||||
let value = field.get_value();
|
||||
headers.insert(key.to_string(), value);
|
||||
Err(e) => warn!(context, "Could not read {} address: {}", key, e),
|
||||
}
|
||||
} else {
|
||||
let value = field.get_value();
|
||||
headers.insert(key.to_string(), value);
|
||||
}
|
||||
}
|
||||
let recipients_new = get_recipients(fields);
|
||||
@@ -2009,28 +2005,6 @@ pub(crate) fn parse_message_id(ids: &str) -> Result<String> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the header overwrites outer header
|
||||
/// when it comes from protected headers.
|
||||
fn is_known(key: &str) -> bool {
|
||||
matches!(
|
||||
key,
|
||||
"return-path"
|
||||
| "date"
|
||||
| "from"
|
||||
| "sender"
|
||||
| "reply-to"
|
||||
| "to"
|
||||
| "cc"
|
||||
| "bcc"
|
||||
| "message-id"
|
||||
| "in-reply-to"
|
||||
| "references"
|
||||
| "subject"
|
||||
| "secure-join"
|
||||
| "list-id"
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns if the header is hidden and must be ignored in the IMF section.
|
||||
pub(crate) fn is_hidden(key: &str) -> bool {
|
||||
matches!(
|
||||
|
||||
Reference in New Issue
Block a user