mirror of
https://github.com/chatmail/core.git
synced 2026-09-22 13:01:21 +03:00
feat!: stop tracking contact verification
Since V2 a contact is its key, there is no address-to-key binding left to verify. The JSONRPC and FFI APIs are unchanged and report nothing as verified. BREAKING CHANGE: the statistics JSON sent to the self-reporting-bot on Android changes: Contacts have `encrypted` instead of `verified` and lose `transitive_chain` properties and message stats have `encrypted` instead of `verified` and `unverified_encrypted`, and securejoin invites lose `already_verified`. The collecting bot stores incoming reports verbatim but analysis will have to make sense of older and newer reports.
This commit is contained in:
@@ -16,7 +16,6 @@ use crate::receive_imf::receive_imf;
|
||||
use crate::securejoin::get_securejoin_qr;
|
||||
use crate::test_utils::TestContext;
|
||||
use crate::test_utils::TestContextManager;
|
||||
use crate::test_utils::mark_as_verified;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_change_primary_self_addr() -> Result<()> {
|
||||
@@ -46,35 +45,21 @@ async fn test_change_primary_self_addr() -> Result<()> {
|
||||
enum ChatForTransition {
|
||||
Single,
|
||||
GroupChat,
|
||||
VerifiedGroup,
|
||||
}
|
||||
use ChatForTransition::*;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_aeap_transition_0() {
|
||||
check_aeap_transition(Single, false).await;
|
||||
check_aeap_transition(Single).await;
|
||||
}
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_aeap_transition_1() {
|
||||
check_aeap_transition(GroupChat, false).await;
|
||||
}
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_aeap_transition_0_verified() {
|
||||
check_aeap_transition(Single, true).await;
|
||||
}
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_aeap_transition_1_verified() {
|
||||
check_aeap_transition(GroupChat, true).await;
|
||||
}
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_aeap_transition_2_verified() {
|
||||
check_aeap_transition(VerifiedGroup, true).await;
|
||||
check_aeap_transition(GroupChat).await;
|
||||
}
|
||||
|
||||
/// Happy path test for AEAP.
|
||||
/// - `chat_for_transition`: Which chat the transition message should be sent in
|
||||
/// - `verified`: Whether Alice and Bob verified each other
|
||||
async fn check_aeap_transition(chat_for_transition: ChatForTransition, verified: bool) {
|
||||
async fn check_aeap_transition(chat_for_transition: ChatForTransition) {
|
||||
const ALICE_NEW_ADDR: &str = "alice2@example.net";
|
||||
|
||||
let mut tcm = TestContextManager::new();
|
||||
@@ -84,19 +69,10 @@ async fn check_aeap_transition(chat_for_transition: ChatForTransition, verified:
|
||||
tcm.send_recv_accept(alice, bob, "Hi").await;
|
||||
tcm.send_recv(bob, alice, "Hi back").await;
|
||||
|
||||
if verified {
|
||||
mark_as_verified(alice, bob).await;
|
||||
mark_as_verified(bob, alice).await;
|
||||
}
|
||||
|
||||
let mut groups = vec![
|
||||
let groups = vec![
|
||||
chat::create_group(bob, "Group 0").await.unwrap(),
|
||||
chat::create_group(bob, "Group 1").await.unwrap(),
|
||||
];
|
||||
if verified {
|
||||
groups.push(chat::create_group(bob, "Group 2").await.unwrap());
|
||||
groups.push(chat::create_group(bob, "Group 3").await.unwrap());
|
||||
}
|
||||
|
||||
let alice_contact = bob.add_or_lookup_contact_id(alice).await;
|
||||
for group in &groups {
|
||||
@@ -111,13 +87,6 @@ async fn check_aeap_transition(chat_for_transition: ChatForTransition, verified:
|
||||
let sent = bob.send_text(groups[1], "group created").await;
|
||||
let group1_alice = alice.recv_msg(&sent).await.chat_id;
|
||||
|
||||
let mut group3_alice = None;
|
||||
if verified {
|
||||
tcm.section("Promoting group 3");
|
||||
let sent = bob.send_text(groups[3], "group created").await;
|
||||
group3_alice = Some(alice.recv_msg(&sent).await.chat_id);
|
||||
}
|
||||
|
||||
tcm.change_addr(alice, ALICE_NEW_ADDR).await;
|
||||
|
||||
tcm.section("Alice sends another message to Bob, this time from her new addr");
|
||||
@@ -125,7 +94,6 @@ async fn check_aeap_transition(chat_for_transition: ChatForTransition, verified:
|
||||
let chat_to_send = match chat_for_transition {
|
||||
Single => alice.create_chat(bob).await.id,
|
||||
GroupChat => group1_alice,
|
||||
VerifiedGroup => group3_alice.expect("No verified group"),
|
||||
};
|
||||
let sent = alice
|
||||
.send_text(chat_to_send, "Hello from my new addr!")
|
||||
@@ -240,16 +208,13 @@ async fn test_write_to_alice_after_aeap() -> Result<()> {
|
||||
let alice_grp_id = chat::create_group(alice, "Group").await?;
|
||||
let qr = get_securejoin_qr(alice, Some(alice_grp_id)).await?;
|
||||
tcm.exec_securejoin_qr(bob, alice, &qr).await;
|
||||
let bob_alice_contact = bob.add_or_lookup_contact(alice).await;
|
||||
assert!(bob_alice_contact.is_verified(bob).await?);
|
||||
let _bob_alice_contact = bob.add_or_lookup_contact(alice).await;
|
||||
let bob_alice_chat = bob.create_chat(alice).await;
|
||||
let bob_unprotected_grp_id = bob.create_group_with_members("Group", &[alice]).await;
|
||||
|
||||
tcm.change_addr(alice, "alice@someotherdomain.xyz").await;
|
||||
let sent = alice.send_text(alice_grp_id, "Hello!").await;
|
||||
bob.recv_msg(&sent).await;
|
||||
|
||||
assert!(bob_alice_contact.is_verified(bob).await?);
|
||||
let bob_alice_chat = Chat::load_from_db(bob, bob_alice_chat.id).await?;
|
||||
let mut msg = Message::new_text("hi".to_string());
|
||||
chat::send_msg(bob, bob_alice_chat.id, &mut msg).await?;
|
||||
|
||||
@@ -6,144 +6,14 @@ use crate::chat::{self, Chat, add_contact_to_chat, remove_contact_from_chat, sen
|
||||
use crate::config::Config;
|
||||
use crate::constants::Chattype;
|
||||
use crate::contact::{Contact, ContactId};
|
||||
use crate::key;
|
||||
use crate::key::self_fingerprint;
|
||||
use crate::message;
|
||||
use crate::message::{Message, Viewtype};
|
||||
use crate::mimefactory::MimeFactory;
|
||||
use crate::mimeparser::SystemMessage;
|
||||
use crate::receive_imf::receive_imf;
|
||||
use crate::securejoin::{get_securejoin_qr, join_securejoin};
|
||||
use crate::stock_str;
|
||||
use crate::test_utils;
|
||||
use crate::test_utils::{
|
||||
E2EE_INFO_MSGS, TestContext, TestContextManager, get_chat_msg, mark_as_verified,
|
||||
};
|
||||
use crate::test_utils::{TestContextManager, get_chat_msg};
|
||||
use crate::tools::SystemTime;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_verified_single_chat_not_broken_by_classical() {
|
||||
check_verified_single_chat_protection_not_broken(true).await;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_verified_single_chat_not_broken_by_device_change() {
|
||||
check_verified_single_chat_protection_not_broken(false).await;
|
||||
}
|
||||
|
||||
async fn check_verified_single_chat_protection_not_broken(by_classical_email: bool) {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = tcm.alice().await;
|
||||
let bob = tcm.bob().await;
|
||||
|
||||
tcm.execute_securejoin(&alice, &bob).await;
|
||||
|
||||
assert_verified(&alice, &bob).await;
|
||||
assert_verified(&bob, &alice).await;
|
||||
|
||||
if by_classical_email {
|
||||
tcm.section("Bob uses a classical MUA to send a message to Alice");
|
||||
receive_imf(
|
||||
&alice,
|
||||
b"Subject: Re: Message from alice\r\n\
|
||||
From: <bob@example.net>\r\n\
|
||||
To: <alice@example.org>\r\n\
|
||||
Date: Mon, 12 Dec 3000 14:33:39 +0000\r\n\
|
||||
Message-ID: <abcd@example.net>\r\n\
|
||||
\r\n\
|
||||
Heyho!\r\n",
|
||||
false,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
alice.assert_warn("unencrypted message").await;
|
||||
let contact = alice.add_or_lookup_contact(&bob).await;
|
||||
assert_eq!(contact.is_verified(&alice).await.unwrap(), true);
|
||||
assert_verified(&alice, &bob).await;
|
||||
} else {
|
||||
tcm.section("Bob sets up another Delta Chat device");
|
||||
let bob2 = tcm.unconfigured().await;
|
||||
bob2.set_name("bob2");
|
||||
bob2.configure_addr("bob@example.net").await;
|
||||
|
||||
SystemTime::shift(std::time::Duration::from_secs(3600));
|
||||
tcm.send_recv(&bob2, &alice, "Using another device now")
|
||||
.await;
|
||||
let contact = alice.add_or_lookup_contact(&bob2).await;
|
||||
assert_eq!(contact.is_verified(&alice).await.unwrap(), false);
|
||||
assert_verified(&alice, &bob).await;
|
||||
}
|
||||
|
||||
tcm.section("Bob sends another message from DC");
|
||||
SystemTime::shift(std::time::Duration::from_secs(3600));
|
||||
tcm.send_recv(&bob, &alice, "Using DC again").await;
|
||||
|
||||
// Bob's chat is marked as verified again
|
||||
assert_verified(&alice, &bob).await;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_create_verified_single_chat() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = tcm.alice().await;
|
||||
let bob = tcm.bob().await;
|
||||
let fiona = tcm.fiona().await;
|
||||
|
||||
tcm.execute_securejoin(&alice, &bob).await;
|
||||
tcm.execute_securejoin(&bob, &fiona).await;
|
||||
assert_verified(&alice, &bob).await;
|
||||
assert_verified(&bob, &alice).await;
|
||||
assert_verified(&bob, &fiona).await;
|
||||
assert_verified(&fiona, &bob).await;
|
||||
|
||||
let group_id = bob
|
||||
.create_group_with_members("Group with everyone", &[&alice, &fiona])
|
||||
.await;
|
||||
bob.set_chat_protected(group_id).await;
|
||||
assert_eq!(
|
||||
get_chat_msg(&bob, group_id, 0, 1).await.get_info_type(),
|
||||
SystemMessage::ChatE2ee
|
||||
);
|
||||
|
||||
{
|
||||
let sent = bob.send_text(group_id, "Heyho").await;
|
||||
alice.recv_msg(&sent).await;
|
||||
|
||||
let msg = fiona.recv_msg(&sent).await;
|
||||
assert_eq!(
|
||||
get_chat_msg(&fiona, msg.chat_id, 0, 2)
|
||||
.await
|
||||
.get_info_type(),
|
||||
SystemMessage::ChatE2ee
|
||||
);
|
||||
}
|
||||
|
||||
// Alice and Fiona should now be verified because of gossip
|
||||
let alice_fiona_contact = alice.add_or_lookup_contact(&fiona).await;
|
||||
assert!(alice_fiona_contact.is_verified(&alice).await.unwrap(),);
|
||||
|
||||
tcm.section("Fiona reinstalls DC");
|
||||
drop(fiona);
|
||||
|
||||
let fiona_new = tcm.unconfigured().await;
|
||||
fiona_new.configure_addr("fiona@example.net").await;
|
||||
key::ensure_secret_key_exists(&fiona_new).await?;
|
||||
|
||||
tcm.send_recv(&fiona_new, &alice, "I have a new device")
|
||||
.await;
|
||||
|
||||
// Alice gets a new chat with new Fiona contact.
|
||||
{
|
||||
let chat = alice.get_chat(&fiona_new).await;
|
||||
|
||||
let msg = get_chat_msg(&alice, chat.id, 1, E2EE_INFO_MSGS + 1).await;
|
||||
assert_eq!(msg.text, "I have a new device");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_missing_key_reexecute_securejoin() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
@@ -168,108 +38,6 @@ async fn test_missing_key_reexecute_securejoin() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Tests that receiving unencrypted message
|
||||
/// does not disable protection of single chat.
|
||||
///
|
||||
/// Instead, an email-chat is created.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_degrade_verified_single_chat() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
alice.allow_unencrypted().await?;
|
||||
|
||||
mark_as_verified(alice, bob).await;
|
||||
|
||||
let alice_chat = alice.create_chat(bob).await;
|
||||
|
||||
receive_imf(
|
||||
alice,
|
||||
b"From: Bob <bob@example.net>\r\n\
|
||||
To: alice@example.org\r\n\
|
||||
Message-ID: <1234-2@example.net>\r\n\
|
||||
\r\n\
|
||||
hello\r\n",
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let msg0 = get_chat_msg(alice, alice_chat.id, 0, 1).await;
|
||||
let enabled = stock_str::messages_e2ee_info_msg(alice);
|
||||
assert_eq!(msg0.text, enabled);
|
||||
assert_eq!(msg0.param.get_cmd(), SystemMessage::ChatE2ee);
|
||||
|
||||
let email_chat = alice.get_email_chat(bob).await;
|
||||
assert!(!email_chat.is_encrypted(alice).await?);
|
||||
let email_msg = get_chat_msg(alice, email_chat.id, 0, 1).await;
|
||||
assert_eq!(email_msg.text, "hello".to_string());
|
||||
assert!(!email_msg.is_system_message());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Alice is offline for some time. mvbox_move is 0.
|
||||
/// When she comes online, first her inbox is synced and then her mvbox.
|
||||
/// This test tests that the messages are still in the right order.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_old_message_4() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
let msg_incoming = test_utils::receive_encrypted_imf(
|
||||
alice,
|
||||
bob,
|
||||
b"From: Bob <bob@example.net>\r\n\
|
||||
To: alice@example.org\r\n\
|
||||
Message-ID: <1234-2-3@example.org>\r\n\
|
||||
Date: Sun, 08 Dec 2019 19:00:27 +0000\r\n\
|
||||
\r\n\
|
||||
Thanks, Alice!\r\n",
|
||||
)
|
||||
.await?;
|
||||
|
||||
let msg_sent = test_utils::receive_encrypted_imf(
|
||||
alice,
|
||||
alice,
|
||||
b"From: alice@example.org\r\n\
|
||||
To: Bob <bob@example.net>\r\n\
|
||||
Message-ID: <1234-2-4@example.org>\r\n\
|
||||
Date: Sat, 07 Dec 2019 19:00:27 +0000\r\n\
|
||||
\r\n\
|
||||
Happy birthday, Bob!\r\n",
|
||||
)
|
||||
.await?;
|
||||
|
||||
// The "Happy birthday" message should be shown first, and then the "Thanks" message
|
||||
assert!(msg_sent.sort_timestamp < msg_incoming.sort_timestamp);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_mdn_doesnt_disable_verification() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = tcm.alice().await;
|
||||
let bob = tcm.bob().await;
|
||||
bob.set_config_bool(Config::MdnsEnabled, true).await?;
|
||||
|
||||
// Alice & Bob verify each other
|
||||
mark_as_verified(&alice, &bob).await;
|
||||
mark_as_verified(&bob, &alice).await;
|
||||
|
||||
let rcvd = tcm.send_recv_accept(&alice, &bob, "Heyho").await;
|
||||
message::markseen_msgs(&bob, vec![rcvd.id]).await?;
|
||||
|
||||
let mimefactory = MimeFactory::from_mdn(&bob, rcvd.from_id, rcvd.rfc724_mid, vec![]).await?;
|
||||
let rendered_msg = mimefactory.render(&bob).await?;
|
||||
let body = rendered_msg.message;
|
||||
receive_imf(&alice, body.as_bytes(), false).await.unwrap();
|
||||
|
||||
assert_verified(&alice, &bob).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_outgoing_mua_msg() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
@@ -277,11 +45,7 @@ async fn test_outgoing_mua_msg() -> Result<()> {
|
||||
let bob = &tcm.bob().await;
|
||||
alice.allow_unencrypted().await?;
|
||||
|
||||
mark_as_verified(alice, bob).await;
|
||||
mark_as_verified(bob, alice).await;
|
||||
|
||||
tcm.send_recv_accept(bob, alice, "Heyho from DC").await;
|
||||
assert_verified(alice, bob).await;
|
||||
|
||||
let sent = receive_imf(
|
||||
alice,
|
||||
@@ -313,7 +77,6 @@ async fn test_outgoing_encrypted_msg() -> Result<()> {
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
|
||||
mark_as_verified(alice, bob).await;
|
||||
let chat_id = alice.create_chat(bob).await.id;
|
||||
let raw = include_bytes!("../../test-data/message/thunderbird_with_autocrypt.eml");
|
||||
receive_imf(alice, raw, false).await?;
|
||||
@@ -327,23 +90,15 @@ async fn test_outgoing_encrypted_msg() -> Result<()> {
|
||||
/// the message is under some circumstances still assigned to the original
|
||||
/// chat (see lookup_chat_by_reply()); this is meant to make aliases
|
||||
/// work nicely.
|
||||
/// However, if the original chat is verified, the unencrypted message
|
||||
/// must NOT be assigned to it (it would be replaced by an error
|
||||
/// message in the verified chat, so, this would just be a usability issue,
|
||||
/// not a security issue).
|
||||
/// However, the unencrypted message must NOT be assigned to an encrypted chat.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_reply() -> Result<()> {
|
||||
for verified in [false, true] {
|
||||
{
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = tcm.alice().await;
|
||||
let bob = tcm.bob().await;
|
||||
alice.allow_unencrypted().await?;
|
||||
|
||||
if verified {
|
||||
mark_as_verified(&alice, &bob).await;
|
||||
mark_as_verified(&bob, &alice).await;
|
||||
}
|
||||
|
||||
tcm.send_recv_accept(&bob, &alice, "Heyho from DC").await;
|
||||
let encrypted_msg = tcm.send_recv(&alice, &bob, "Heyho back").await;
|
||||
|
||||
@@ -372,8 +127,7 @@ async fn test_reply() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Tests that message from old DC setup does not break
|
||||
/// new verified chat.
|
||||
/// Tests that a message from an old DC setup does not break the new chat.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_message_from_old_dc_setup() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
@@ -381,7 +135,6 @@ async fn test_message_from_old_dc_setup() -> Result<()> {
|
||||
let bob_old = &tcm.unconfigured().await;
|
||||
|
||||
bob_old.configure_addr("bob@example.net").await;
|
||||
mark_as_verified(bob_old, alice).await;
|
||||
let chat = bob_old.create_chat(alice).await;
|
||||
let sent_old = bob_old
|
||||
.send_text(chat.id, "Soon i'll have a new device")
|
||||
@@ -391,55 +144,20 @@ async fn test_message_from_old_dc_setup() -> Result<()> {
|
||||
tcm.section("Bob reinstalls DC");
|
||||
let bob = &tcm.bob().await;
|
||||
|
||||
mark_as_verified(alice, bob).await;
|
||||
mark_as_verified(bob, alice).await;
|
||||
|
||||
tcm.send_recv(bob, alice, "Now i have it!").await;
|
||||
assert_verified(alice, bob).await;
|
||||
|
||||
let msg = alice.recv_msg(&sent_old).await;
|
||||
assert!(msg.get_showpadlock());
|
||||
let contact = alice.add_or_lookup_contact(bob).await;
|
||||
|
||||
// The outdated Bob's Autocrypt header isn't applied
|
||||
// and the message goes to another chat, so the verification preserves.
|
||||
assert!(contact.is_verified(alice).await.unwrap());
|
||||
// The outdated Bob's Autocrypt header isn't applied,
|
||||
// so the message goes to another chat.
|
||||
assert_ne!(contact.id, msg.from_id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Regression test for the following bug:
|
||||
///
|
||||
/// - Scan your chat partner's QR Code
|
||||
/// - They change devices
|
||||
/// - Scan their QR code again
|
||||
///
|
||||
/// -> The re-verification fails.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_verify_then_verify_again() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = tcm.alice().await;
|
||||
let bob = tcm.bob().await;
|
||||
|
||||
mark_as_verified(&alice, &bob).await;
|
||||
mark_as_verified(&bob, &alice).await;
|
||||
|
||||
alice.create_chat(&bob).await;
|
||||
assert_verified(&alice, &bob).await;
|
||||
|
||||
tcm.section("Bob reinstalls DC");
|
||||
drop(bob);
|
||||
let bob_new = tcm.unconfigured().await;
|
||||
bob_new.configure_addr("bob@example.net").await;
|
||||
key::ensure_secret_key_exists(&bob_new).await?;
|
||||
|
||||
tcm.execute_securejoin(&bob_new, &alice).await;
|
||||
assert_verified(&alice, &bob_new).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Tests that on the second device of a group creator the first message is
|
||||
/// `SystemMessage::ChatE2ee` and the second one is the message populating the group.
|
||||
/// Tests that on a second device the e2ee info message
|
||||
/// sorts before the older message that created the group.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_create_grp_multidev() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
@@ -473,7 +191,7 @@ async fn test_create_grp_multidev() -> Result<()> {
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_verified_member_added_reordering() -> Result<()> {
|
||||
async fn test_member_added_reordering() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
@@ -502,7 +220,7 @@ async fn test_verified_member_added_reordering() -> Result<()> {
|
||||
let bob_sent_message = bob.send_text(bob_chat_id, "Hi").await;
|
||||
|
||||
// Fiona receives message from Bob before receiving
|
||||
// "Member added" message, so unverified group is created.
|
||||
// the "Member added" message, so she cannot send yet.
|
||||
let fiona_received_message = fiona.recv_msg(&bob_sent_message).await;
|
||||
let fiona_chat = Chat::load_from_db(fiona, fiona_received_message.chat_id).await?;
|
||||
assert!(!fiona_chat.can_send(fiona).await?);
|
||||
@@ -518,16 +236,12 @@ async fn test_verified_member_added_reordering() -> Result<()> {
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_no_unencrypted_name_if_encrypted() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
for verified in [false, true] {
|
||||
{
|
||||
let alice = tcm.alice().await;
|
||||
let bob = tcm.bob().await;
|
||||
bob.set_config(Config::Displayname, Some("Bob Smith"))
|
||||
.await?;
|
||||
if verified {
|
||||
mark_as_verified(&bob, &alice).await;
|
||||
} else {
|
||||
tcm.send_recv_accept(&alice, &bob, "hi").await;
|
||||
}
|
||||
tcm.send_recv_accept(&alice, &bob, "hi").await;
|
||||
|
||||
let chat_id = bob.create_chat(&alice).await.id;
|
||||
let msg = &bob.send_text(chat_id, "hi").await;
|
||||
@@ -544,7 +258,7 @@ async fn test_no_unencrypted_name_if_encrypted() -> Result<()> {
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_verified_lost_member_added() -> Result<()> {
|
||||
async fn test_lost_member_added() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
@@ -609,10 +323,9 @@ async fn test_verified_lost_member_added() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Tests handling of resent .xdc arriving before "Member added"
|
||||
/// in a verified group
|
||||
/// Tests handling of resent .xdc arriving before "Member added".
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_verified_chat_editor_reordering() -> Result<()> {
|
||||
async fn test_chat_editor_reordering() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
@@ -620,7 +333,7 @@ async fn test_verified_chat_editor_reordering() -> Result<()> {
|
||||
|
||||
tcm.execute_securejoin(alice, bob).await;
|
||||
|
||||
tcm.section("Alice creates a protected group with Bob");
|
||||
tcm.section("Alice creates a group with Bob");
|
||||
let alice_chat_id = alice.create_group_with_members("Group", &[bob]).await;
|
||||
let alice_sent = alice.send_text(alice_chat_id, "Hi!").await;
|
||||
let bob_chat_id = bob.recv_msg(&alice_sent).await.chat_id;
|
||||
@@ -667,9 +380,6 @@ async fn test_verified_chat_editor_reordering() -> Result<()> {
|
||||
tcm.section("Charlie receives resent webxdc before member added");
|
||||
let charlie_received_xdc = charlie.recv_msg(&bob.pop_sent_msg().await).await;
|
||||
|
||||
// The message should not be replaced with
|
||||
// "The message was sent with non-verified encryption." text
|
||||
// just because it was reordered.
|
||||
assert_eq!(charlie_received_xdc.viewtype, Viewtype::Webxdc);
|
||||
|
||||
tcm.section("Charlie receives member added message");
|
||||
@@ -677,122 +387,8 @@ async fn test_verified_chat_editor_reordering() -> Result<()> {
|
||||
charlie
|
||||
.golden_test_chat(
|
||||
charlie_received_xdc.chat_id,
|
||||
"verified_chats_editor_reordering",
|
||||
"encrypted_chats_editor_reordering",
|
||||
)
|
||||
.await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Tests that already verified contact
|
||||
/// does not get a new "verifier"
|
||||
/// via gossip.
|
||||
///
|
||||
/// Directly verifying is still possible.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_no_reverification() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
let charlie = &tcm.charlie().await;
|
||||
let fiona = &tcm.fiona().await;
|
||||
|
||||
tcm.execute_securejoin(alice, bob).await;
|
||||
tcm.execute_securejoin(alice, charlie).await;
|
||||
tcm.execute_securejoin(alice, fiona).await;
|
||||
|
||||
tcm.section("Alice creates a protected group with Bob, Charlie and Fiona");
|
||||
let alice_chat_id = alice
|
||||
.create_group_with_members("Group", &[bob, charlie, fiona])
|
||||
.await;
|
||||
alice.set_chat_protected(alice_chat_id).await;
|
||||
let alice_sent = alice.send_text(alice_chat_id, "Hi!").await;
|
||||
let bob_rcvd_msg = bob.recv_msg(&alice_sent).await;
|
||||
let bob_alice_id = bob_rcvd_msg.from_id;
|
||||
|
||||
// Charlie is verified by Alice for Bob.
|
||||
let bob_charlie_contact = bob.add_or_lookup_contact(charlie).await;
|
||||
assert_eq!(
|
||||
bob_charlie_contact
|
||||
.get_verifier_id(bob)
|
||||
.await?
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
bob_alice_id
|
||||
);
|
||||
|
||||
let fiona_rcvd_msg = fiona.recv_msg(&alice_sent).await;
|
||||
let fiona_chat_id = fiona_rcvd_msg.chat_id;
|
||||
let fiona_sent = fiona.send_text(fiona_chat_id, "Post by Fiona").await;
|
||||
bob.recv_msg(&fiona_sent).await;
|
||||
|
||||
// Charlie should still be verified by Alice, not by Fiona.
|
||||
let bob_charlie_contact = bob.add_or_lookup_contact(charlie).await;
|
||||
assert_eq!(
|
||||
bob_charlie_contact
|
||||
.get_verifier_id(bob)
|
||||
.await?
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
bob_alice_id
|
||||
);
|
||||
|
||||
// Bob can still verify Charlie directly.
|
||||
tcm.execute_securejoin(bob, charlie).await;
|
||||
let bob_charlie_contact = bob.add_or_lookup_contact(charlie).await;
|
||||
assert_eq!(
|
||||
bob_charlie_contact
|
||||
.get_verifier_id(bob)
|
||||
.await?
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
ContactId::SELF
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Tests that if our second device observes
|
||||
/// us gossiping a verification,
|
||||
/// it is not treated as direct verification.
|
||||
///
|
||||
/// Direct verifications should only happen
|
||||
/// as a result of SecureJoin.
|
||||
/// If we see our second device gossiping
|
||||
/// a verification of some contact,
|
||||
/// it may be indirect verification,
|
||||
/// so we should mark the contact as verified,
|
||||
/// but with unknown verifier.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_no_single_verification_via_bcc() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let alice2 = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
|
||||
mark_as_verified(alice, bob).await;
|
||||
|
||||
let alice_chat_id = alice.create_chat_id(bob).await;
|
||||
alice.set_chat_protected(alice_chat_id).await;
|
||||
let alice_sent_msg = alice.send_text(alice_chat_id, "Hello!").await;
|
||||
alice2.recv_msg(&alice_sent_msg).await;
|
||||
|
||||
// Alice 2 observes Alice 1 gossiping verification for Bob.
|
||||
// Alice 2 does not know if Alice 1 has verified Bob directly though.
|
||||
let alice2_bob_contact = alice2.add_or_lookup_contact(bob).await;
|
||||
assert_eq!(alice2_bob_contact.is_verified(alice2).await?, true);
|
||||
|
||||
// There is some verifier, but it is unknown to Alice's second device.
|
||||
assert_eq!(
|
||||
alice2_bob_contact.get_verifier_id(alice2).await?,
|
||||
Some(None)
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// ============== Helper Functions ==============
|
||||
|
||||
async fn assert_verified(this: &TestContext, other: &TestContext) {
|
||||
let contact = this.add_or_lookup_contact(other).await;
|
||||
assert_eq!(contact.is_verified(this).await.unwrap(), true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user