mirror of
https://github.com/chatmail/core.git
synced 2026-04-28 19:06:35 +03:00
fix: Don't reverify contacts by SELF on receipt of a message from another device
Also verify not yet verified contacts w/o setting a verifier for them (in the db it's stored as `verifier_id=id` though) because we don't know who verified them for another device.
This commit is contained in:
@@ -1948,16 +1948,21 @@ pub(crate) async fn update_last_seen(
|
||||
}
|
||||
|
||||
/// Marks contact `contact_id` as verified by `verifier_id`.
|
||||
///
|
||||
/// `verifier_id == None` means that the verifier is unknown.
|
||||
pub(crate) async fn mark_contact_id_as_verified(
|
||||
context: &Context,
|
||||
contact_id: ContactId,
|
||||
verifier_id: ContactId,
|
||||
verifier_id: Option<ContactId>,
|
||||
) -> Result<()> {
|
||||
ensure_and_debug_assert_ne!(contact_id, ContactId::SELF,);
|
||||
ensure_and_debug_assert_ne!(
|
||||
contact_id,
|
||||
Some(contact_id),
|
||||
verifier_id,
|
||||
"Contact cannot be verified by self",
|
||||
);
|
||||
let update = verifier_id == Some(ContactId::SELF);
|
||||
let verifier_id = verifier_id.unwrap_or(contact_id);
|
||||
context
|
||||
.sql
|
||||
.transaction(|transaction| {
|
||||
@@ -1983,8 +1988,8 @@ pub(crate) async fn mark_contact_id_as_verified(
|
||||
}
|
||||
transaction.execute(
|
||||
"UPDATE contacts SET verifier=?1
|
||||
WHERE id=?2 AND (verifier=0 OR ?1=?3)",
|
||||
(verifier_id, contact_id, ContactId::SELF),
|
||||
WHERE id=?2 AND (verifier=0 OR ?3)",
|
||||
(verifier_id, contact_id, update),
|
||||
)?;
|
||||
Ok(())
|
||||
})
|
||||
|
||||
@@ -1215,7 +1215,7 @@ impl Context {
|
||||
.await?
|
||||
.first()
|
||||
.context("Self reporting bot vCard does not contain a contact")?;
|
||||
mark_contact_id_as_verified(self, contact_id, ContactId::SELF).await?;
|
||||
mark_contact_id_as_verified(self, contact_id, Some(ContactId::SELF)).await?;
|
||||
|
||||
let chat_id = ChatId::create_for_contact(self, contact_id).await?;
|
||||
chat_id
|
||||
|
||||
@@ -3691,12 +3691,13 @@ async fn mark_recipients_as_verified(
|
||||
if mimeparser.get_header(HeaderDef::ChatVerified).is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
let verifier_id = Some(from_id).filter(|&id| id != ContactId::SELF);
|
||||
for to_id in to_ids.iter().filter_map(|&x| x) {
|
||||
if to_id == ContactId::SELF || to_id == from_id {
|
||||
continue;
|
||||
}
|
||||
|
||||
mark_contact_id_as_verified(context, to_id, from_id).await?;
|
||||
mark_contact_id_as_verified(context, to_id, verifier_id).await?;
|
||||
ChatId::set_protection_for_contact(context, to_id, mimeparser.timestamp_sent).await?;
|
||||
}
|
||||
|
||||
|
||||
@@ -5154,6 +5154,32 @@ async fn test_unverified_member_msg() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_dont_reverify_by_self_on_outgoing_msg() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let a0 = &tcm.alice().await;
|
||||
let a1 = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
let fiona = &tcm.fiona().await;
|
||||
|
||||
let bob_chat_id = chat::create_group_chat(bob, ProtectionStatus::Protected, "Group").await?;
|
||||
let qr = get_securejoin_qr(bob, Some(bob_chat_id)).await?;
|
||||
tcm.exec_securejoin_qr(fiona, bob, &qr).await;
|
||||
tcm.exec_securejoin_qr(a0, bob, &qr).await;
|
||||
tcm.exec_securejoin_qr(a1, bob, &qr).await;
|
||||
|
||||
let a0_chat_id = a0.get_last_msg().await.chat_id;
|
||||
let a0_sent_msg = a0.send_text(a0_chat_id, "Hi").await;
|
||||
a1.recv_msg(&a0_sent_msg).await;
|
||||
let a1_bob_id = a1.add_or_lookup_contact_id(bob).await;
|
||||
let a1_fiona = a1.add_or_lookup_contact(fiona).await;
|
||||
assert_eq!(
|
||||
a1_fiona.get_verifier_id(a1).await?.unwrap().unwrap(),
|
||||
a1_bob_id
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_sanitize_filename_in_received() -> Result<()> {
|
||||
let alice = &TestContext::new_alice().await;
|
||||
|
||||
@@ -210,7 +210,7 @@ async fn verify_sender_by_fingerprint(
|
||||
let contact = Contact::get_by_id(context, contact_id).await?;
|
||||
let is_verified = contact.fingerprint().is_some_and(|fp| &fp == fingerprint);
|
||||
if is_verified {
|
||||
mark_contact_id_as_verified(context, contact_id, ContactId::SELF).await?;
|
||||
mark_contact_id_as_verified(context, contact_id, Some(ContactId::SELF)).await?;
|
||||
}
|
||||
Ok(is_verified)
|
||||
}
|
||||
@@ -548,7 +548,7 @@ pub(crate) async fn observe_securejoin_on_other_device(
|
||||
return Ok(HandshakeMessage::Ignore);
|
||||
}
|
||||
|
||||
mark_contact_id_as_verified(context, contact_id, ContactId::SELF).await?;
|
||||
mark_contact_id_as_verified(context, contact_id, Some(ContactId::SELF)).await?;
|
||||
|
||||
ChatId::set_protection_for_contact(context, contact_id, mime_message.timestamp_sent).await?;
|
||||
|
||||
|
||||
@@ -1420,7 +1420,7 @@ fn print_logevent(logevent: &LogEvent) {
|
||||
/// Saves the other account's public key as verified
|
||||
pub(crate) async fn mark_as_verified(this: &TestContext, other: &TestContext) {
|
||||
let contact_id = this.add_or_lookup_contact_id(other).await;
|
||||
mark_contact_id_as_verified(this, contact_id, ContactId::SELF)
|
||||
mark_contact_id_as_verified(this, contact_id, Some(ContactId::SELF))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user