mirror of
https://github.com/chatmail/core.git
synced 2026-05-22 16:26:31 +03:00
fix: Ignore hidden headers in IMF section
Hidden headers are nonstandard, so they aren't DKIM-signed by e.g. OpenDKIM if they appear in IMF section.
This commit is contained in:
@@ -23,7 +23,7 @@ use crate::e2ee::EncryptHelper;
|
|||||||
use crate::ephemeral::Timer as EphemeralTimer;
|
use crate::ephemeral::Timer as EphemeralTimer;
|
||||||
use crate::location;
|
use crate::location;
|
||||||
use crate::message::{self, Message, MsgId, Viewtype};
|
use crate::message::{self, Message, MsgId, Viewtype};
|
||||||
use crate::mimeparser::SystemMessage;
|
use crate::mimeparser::{is_hidden, SystemMessage};
|
||||||
use crate::param::Param;
|
use crate::param::Param;
|
||||||
use crate::peer_channels::create_iroh_header;
|
use crate::peer_channels::create_iroh_header;
|
||||||
use crate::peerstate::Peerstate;
|
use crate::peerstate::Peerstate;
|
||||||
@@ -869,11 +869,7 @@ impl MimeFactory {
|
|||||||
if header_name == "message-id" {
|
if header_name == "message-id" {
|
||||||
unprotected_headers.push(header.clone());
|
unprotected_headers.push(header.clone());
|
||||||
hidden_headers.push(header.clone());
|
hidden_headers.push(header.clone());
|
||||||
} else if header_name == "chat-user-avatar"
|
} else if is_hidden(&header_name) {
|
||||||
|| header_name == "chat-group-avatar"
|
|
||||||
|| header_name == "chat-delete"
|
|
||||||
|| header_name == "chat-edit"
|
|
||||||
{
|
|
||||||
hidden_headers.push(header.clone());
|
hidden_headers.push(header.clone());
|
||||||
} else if header_name == "autocrypt"
|
} else if header_name == "autocrypt"
|
||||||
&& !context.get_config_bool(Config::ProtectAutocrypt).await?
|
&& !context.get_config_bool(Config::ProtectAutocrypt).await?
|
||||||
|
|||||||
@@ -253,6 +253,7 @@ impl MimeMessage {
|
|||||||
&mut chat_disposition_notification_to,
|
&mut chat_disposition_notification_to,
|
||||||
&mail.headers,
|
&mail.headers,
|
||||||
);
|
);
|
||||||
|
headers.retain(|k, _| !is_hidden(k));
|
||||||
|
|
||||||
// Parse hidden headers.
|
// Parse hidden headers.
|
||||||
let mimetype = mail.ctype.mimetype.parse::<Mime>()?;
|
let mimetype = mail.ctype.mimetype.parse::<Mime>()?;
|
||||||
@@ -289,12 +290,7 @@ impl MimeMessage {
|
|||||||
let key = field.get_key().to_lowercase();
|
let key = field.get_key().to_lowercase();
|
||||||
|
|
||||||
// For now only avatar headers can be hidden.
|
// For now only avatar headers can be hidden.
|
||||||
if !headers.contains_key(&key)
|
if !headers.contains_key(&key) && is_hidden(&key) {
|
||||||
&& (key == "chat-user-avatar"
|
|
||||||
|| key == "chat-group-avatar"
|
|
||||||
|| key == "chat-delete"
|
|
||||||
|| key == "chat-edit")
|
|
||||||
{
|
|
||||||
headers.insert(key.to_string(), field.get_value());
|
headers.insert(key.to_string(), field.get_value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1988,6 +1984,14 @@ fn is_known(key: &str) -> bool {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns if the header is hidden and must be ignored in the IMF section.
|
||||||
|
pub(crate) fn is_hidden(key: &str) -> bool {
|
||||||
|
matches!(
|
||||||
|
key,
|
||||||
|
"chat-user-avatar" | "chat-group-avatar" | "chat-delete" | "chat-edit"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Parsed MIME part.
|
/// Parsed MIME part.
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct Part {
|
pub struct Part {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use mailparse::ParsedMail;
|
use mailparse::ParsedMail;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
chat,
|
chat,
|
||||||
chatlist::Chatlist,
|
chatlist::Chatlist,
|
||||||
constants::{Blocked, DC_DESIRED_TEXT_LEN, DC_ELLIPSIS},
|
constants::{self, Blocked, DC_DESIRED_TEXT_LEN, DC_ELLIPSIS},
|
||||||
message::{MessageState, MessengerMessage},
|
message::{MessageState, MessengerMessage},
|
||||||
receive_imf::receive_imf,
|
receive_imf::receive_imf,
|
||||||
test_utils::{TestContext, TestContextManager},
|
test_utils::{TestContext, TestContextManager},
|
||||||
@@ -1916,3 +1917,45 @@ This is the epilogue. It is also to be ignored.";
|
|||||||
"This is explicitly typed plain US-ASCII text.\r\nIt DOES end with a linebreak.\r\n"
|
"This is explicitly typed plain US-ASCII text.\r\nIt DOES end with a linebreak.\r\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn test_chat_edit_imf_header() -> Result<()> {
|
||||||
|
let mut tcm = TestContextManager::new();
|
||||||
|
let alice = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
|
let alice_chat = alice.create_email_chat(bob).await;
|
||||||
|
|
||||||
|
// Alice sends a message, then sends an invalid edit request.
|
||||||
|
let sent1 = alice.send_text(alice_chat.id, "foo").await;
|
||||||
|
let alice_msg = sent1.load_from_db().await;
|
||||||
|
assert_eq!(alice_chat.id.get_msg_cnt(alice).await?, 1);
|
||||||
|
|
||||||
|
chat::send_edit_request(alice, alice_msg.id, "bar".to_string()).await?;
|
||||||
|
let mut sent2 = alice.pop_sent_msg().await;
|
||||||
|
let mut s0 = String::new();
|
||||||
|
let mut s1 = String::new();
|
||||||
|
for l in sent2.payload.lines() {
|
||||||
|
if l.starts_with("Chat-Edit:") {
|
||||||
|
s1 += l;
|
||||||
|
s1 += "\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
s0 += l;
|
||||||
|
s0 += "\n";
|
||||||
|
if l.starts_with("Message-ID:") && s1.is_empty() {
|
||||||
|
s1 = mem::take(&mut s0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sent2.payload = s1 + &s0;
|
||||||
|
|
||||||
|
// Bob receives both messages, the edit request with "Chat-Edit" in IMF headers is
|
||||||
|
// received as text message.
|
||||||
|
let bob_msg = bob.recv_msg(&sent1).await;
|
||||||
|
assert_eq!(bob_msg.text, "foo");
|
||||||
|
assert_eq!(bob_msg.chat_id.get_msg_cnt(bob).await?, 1);
|
||||||
|
let bob_msg = bob.recv_msg(&sent2).await;
|
||||||
|
assert_eq!(bob_msg.text, constants::EDITED_PREFIX.to_string() + "bar");
|
||||||
|
assert_eq!(bob_msg.chat_id.get_msg_cnt(bob).await?, 2);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
Chat-Group-ID: WVnDtF5azch
|
Chat-Group-ID: WVnDtF5azch
|
||||||
Chat-Group-Name: =?utf-8?q?testgr1?=
|
Chat-Group-Name: =?utf-8?q?testgr1?=
|
||||||
Chat-Group-Avatar: group-image.png
|
|
||||||
Chat-User-Avatar: avatar.png
|
|
||||||
Subject: =?utf-8?q?Chat=3A_testgr1=3A_hi!_?=
|
Subject: =?utf-8?q?Chat=3A_testgr1=3A_hi!_?=
|
||||||
Date: Thu, 12 Dec 2019 17:24:03 +0000
|
Date: Thu, 12 Dec 2019 17:24:03 +0000
|
||||||
X-Mailer: Delta Chat Core 1.0.0-beta.15/CLI
|
X-Mailer: Delta Chat Core 1.0.0-beta.15/CLI
|
||||||
@@ -14,6 +12,8 @@ Content-Type: multipart/mixed; boundary="LV8nfXkpyyn39fsVyoB1b29PKDMeb5"
|
|||||||
|
|
||||||
--LV8nfXkpyyn39fsVyoB1b29PKDMeb5
|
--LV8nfXkpyyn39fsVyoB1b29PKDMeb5
|
||||||
Content-Type: text/plain; charset=utf-8
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
Chat-Group-Avatar: group-image.png
|
||||||
|
Chat-User-Avatar: avatar.png
|
||||||
|
|
||||||
hi!
|
hi!
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
Chat-User-Avatar: avatar.png
|
|
||||||
Subject: =?utf-8?q?Chat=3A_this_is_a_message_with_a_=2E=2E=2E?=
|
Subject: =?utf-8?q?Chat=3A_this_is_a_message_with_a_=2E=2E=2E?=
|
||||||
Message-ID: Mr.wOBwZNbBTVt.NZpmQDwWoNk@example.org
|
Message-ID: Mr.wOBwZNbBTVt.NZpmQDwWoNk@example.org
|
||||||
In-Reply-To: Mr.ETXqza5-WpB.zDEYOLECxAw@example.org
|
In-Reply-To: Mr.ETXqza5-WpB.zDEYOLECxAw@example.org
|
||||||
@@ -12,6 +11,7 @@ Content-Type: multipart/mixed; boundary="luTiGu6GBoVLCvTkzVtmZmwsmhkNMw"
|
|||||||
|
|
||||||
--luTiGu6GBoVLCvTkzVtmZmwsmhkNMw
|
--luTiGu6GBoVLCvTkzVtmZmwsmhkNMw
|
||||||
Content-Type: text/plain; charset=utf-8
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
Chat-User-Avatar: avatar.png
|
||||||
|
|
||||||
this is a message with a profile-image attached
|
this is a message with a profile-image attached
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
Content-Type: text/plain; charset=utf-8
|
|
||||||
Chat-User-Avatar: 0
|
|
||||||
Subject: =?utf-8?q?Chat=3A_profile_image_deleted?=
|
Subject: =?utf-8?q?Chat=3A_profile_image_deleted?=
|
||||||
Message-ID: Mr.tsgoJgn-cBf.0TkFWKJzeSp@example.org
|
Message-ID: Mr.tsgoJgn-cBf.0TkFWKJzeSp@example.org
|
||||||
Date: Sun, 08 Dec 2019 23:28:30 +0000
|
Date: Sun, 08 Dec 2019 23:28:30 +0000
|
||||||
@@ -7,8 +5,16 @@ X-Mailer: Delta Chat Core 1.0.0-beta.12/CLI
|
|||||||
Chat-Version: 1.0
|
Chat-Version: 1.0
|
||||||
To: <tunis3@example>
|
To: <tunis3@example>
|
||||||
From: "=?utf-8?q??=" <tunis4@example.org>
|
From: "=?utf-8?q??=" <tunis4@example.org>
|
||||||
|
Content-Type: multipart/mixed; boundary="luTiGu6GBoVLCvTkzVtmZmwsmhkNMw"
|
||||||
|
|
||||||
|
|
||||||
|
--luTiGu6GBoVLCvTkzVtmZmwsmhkNMw
|
||||||
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
Chat-User-Avatar: 0
|
||||||
|
|
||||||
profile image deleted
|
profile image deleted
|
||||||
|
|
||||||
--
|
--
|
||||||
Sent with my Delta Chat Messenger: https://delta.chat
|
Sent with my Delta Chat Messenger: https://delta.chat
|
||||||
|
|
||||||
|
--luTiGu6GBoVLCvTkzVtmZmwsmhkNMw--
|
||||||
|
|||||||
Reference in New Issue
Block a user