Skip to content

Commit 28cce5e

Browse files
committed
fix: determine whether a message is an own message by looking at signature. multiple devices can temporarly have different sets of self addresses, and still need to properly recognize incoming versus outgoing messages. Disclaimer: some LLM tooling was initially involved but i went over everything by hand, and also addressed review comments.
1 parent 3b87e27 commit 28cce5e

2 files changed

Lines changed: 42 additions & 4 deletions

File tree

src/mimeparser.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ impl MimeMessage {
373373
hop_info += "\n\n";
374374
hop_info += &dkim_results.to_string();
375375

376-
let incoming = !context.is_self_addr(&from.addr).await?;
376+
let from_is_not_self_addr = !context.is_self_addr(&from.addr).await?;
377377

378378
let mut aheader_values = mail.headers.get_all_values(HeaderDef::Autocrypt.into());
379379

@@ -438,7 +438,7 @@ impl MimeMessage {
438438
};
439439

440440
let mut autocrypt_header = None;
441-
if incoming {
441+
if from_is_not_self_addr {
442442
// See `get_all_addresses_from_header()` for why we take the last valid header.
443443
for val in aheader_values.iter().rev() {
444444
autocrypt_header = match Aheader::from_str(val) {
@@ -469,7 +469,7 @@ impl MimeMessage {
469469
None
470470
};
471471

472-
let mut public_keyring = if incoming {
472+
let mut public_keyring = if from_is_not_self_addr {
473473
if let Some(autocrypt_header) = autocrypt_header {
474474
vec![autocrypt_header.public_key]
475475
} else {
@@ -654,6 +654,15 @@ impl MimeMessage {
654654
.into_iter()
655655
.last()
656656
.map(|(fp, recipient_fps)| (fp, recipient_fps.into_iter().collect::<HashSet<_>>()));
657+
658+
let incoming = if let Some((ref sig_fp, _)) = signature {
659+
sig_fp.hex() != key::self_fingerprint(context).await?
660+
} else {
661+
// rare case of getting a cleartext message
662+
// so we determine 'incoming' flag by From-address
663+
from_is_not_self_addr
664+
};
665+
657666
let mut parser = MimeMessage {
658667
parts: Vec::new(),
659668
headers,

src/receive_imf/receive_imf_tests.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ use crate::constants::DC_GCL_FOR_FORWARDING;
1313
use crate::contact;
1414
use crate::imap::prefetch_should_download;
1515
use crate::imex::{ImexMode, imex};
16+
use crate::key;
1617
use crate::securejoin::get_securejoin_qr;
1718
use crate::test_utils::{
18-
E2EE_INFO_MSGS, TestContext, TestContextManager, get_chat_msg, mark_as_verified,
19+
E2EE_INFO_MSGS, TestContext, TestContextManager, alice_keypair, get_chat_msg, mark_as_verified,
1920
};
2021
use crate::tools::{SystemTime, time};
2122

@@ -5561,3 +5562,31 @@ async fn test_calendar_alternative() -> Result<()> {
55615562

55625563
Ok(())
55635564
}
5565+
5566+
/// Tests that outgoing encrypted messages are detected
5567+
/// by verifying own signature, completely ignoring From address.
5568+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
5569+
async fn test_outgoing_determined_by_signature() -> Result<()> {
5570+
let mut tcm = TestContextManager::new();
5571+
let alice = &tcm.alice().await;
5572+
let bob = &tcm.bob().await;
5573+
5574+
// alice_dev2: same key, different address.
5575+
let different_from = "very@different.from";
5576+
assert!(!alice.is_self_addr(different_from).await?);
5577+
let alice_dev2 = &tcm.unconfigured().await;
5578+
alice_dev2.configure_addr(different_from).await;
5579+
key::store_self_keypair(alice_dev2, &alice_keypair()).await?;
5580+
assert_ne!(
5581+
alice.get_config(Config::Addr).await?.unwrap(),
5582+
different_from
5583+
);
5584+
5585+
// Send message from alice_dev2 and check alice sees it as outgoing
5586+
let chat_id = alice_dev2.create_chat_id(bob).await;
5587+
let sent_msg = alice_dev2.send_text(chat_id, "hello from new device").await;
5588+
let msg = alice.recv_msg(&sent_msg).await;
5589+
assert_eq!(msg.state, MessageState::OutDelivered);
5590+
5591+
Ok(())
5592+
}

0 commit comments

Comments
 (0)