Skip to content

Commit 91d5151

Browse files
committed
feat: ignore encryption preferences
Always prefer encryption if it is available.
1 parent 59e3ac2 commit 91d5151

File tree

9 files changed

+33
-310
lines changed

9 files changed

+33
-310
lines changed

python/src/deltachat/testplugin.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,8 +423,6 @@ def get_next_liveconfig(self):
423423
where we can make valid SMTP and IMAP connections with.
424424
"""
425425
configdict = next(self._liveconfig_producer).copy()
426-
if "e2ee_enabled" not in configdict:
427-
configdict["e2ee_enabled"] = "1"
428426

429427
if self.pytestconfig.getoption("--strict-tls"):
430428
# Enable strict certificate checks for online accounts

python/tests/test_1_online.py

Lines changed: 0 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -919,64 +919,6 @@ def test_gossip_optimization(acfactory, lp):
919919
assert gossiped_timestamp == int(msg.time_sent.timestamp())
920920

921921

922-
def test_gossip_encryption_preference(acfactory, lp):
923-
"""Test that encryption preference of group members is gossiped to new members.
924-
This is a Delta Chat extension to Autocrypt 1.1.0, which Autocrypt-Gossip headers
925-
SHOULD NOT contain encryption preference.
926-
"""
927-
ac1, ac2, ac3 = acfactory.get_online_accounts(3)
928-
929-
lp.sec("ac1 learns that ac2 prefers encryption")
930-
ac1.create_chat(ac2)
931-
msg = ac2.create_chat(ac1).send_text("first message")
932-
msg = ac1._evtracker.wait_next_incoming_message()
933-
assert msg.text == "first message"
934-
assert not msg.is_encrypted()
935-
res = "End-to-end encryption preferred:\n{}".format(ac2.get_config("addr"))
936-
assert msg.chat.get_encryption_info() == res
937-
lp.sec("ac2 learns that ac3 prefers encryption")
938-
ac2.create_chat(ac3)
939-
msg = ac3.create_chat(ac2).send_text("I prefer encryption")
940-
msg = ac2._evtracker.wait_next_incoming_message()
941-
assert msg.text == "I prefer encryption"
942-
assert not msg.is_encrypted()
943-
944-
lp.sec("ac3 does not know that ac1 prefers encryption")
945-
ac1.create_chat(ac3)
946-
chat = ac3.create_chat(ac1)
947-
res = "No encryption:\n{}".format(ac1.get_config("addr"))
948-
assert chat.get_encryption_info() == res
949-
msg = chat.send_text("not encrypted")
950-
msg = ac1._evtracker.wait_next_incoming_message()
951-
assert msg.text == "not encrypted"
952-
assert not msg.is_encrypted()
953-
954-
lp.sec("ac1 creates a group chat with ac2")
955-
group_chat = ac1.create_group_chat("hello")
956-
group_chat.add_contact(ac2)
957-
encryption_info = group_chat.get_encryption_info()
958-
res = "End-to-end encryption preferred:\n{}".format(ac2.get_config("addr"))
959-
assert encryption_info == res
960-
msg = group_chat.send_text("hi")
961-
962-
msg = ac2._evtracker.wait_next_incoming_message()
963-
assert msg.is_encrypted()
964-
assert msg.text == "hi"
965-
966-
lp.sec("ac2 adds ac3 to the group")
967-
msg.chat.add_contact(ac3)
968-
assert msg.is_encrypted()
969-
970-
lp.sec("ac3 learns that ac1 prefers encryption")
971-
msg = ac3._evtracker.wait_next_incoming_message()
972-
encryption_info = msg.chat.get_encryption_info().splitlines()
973-
assert encryption_info[0] == "End-to-end encryption preferred:"
974-
assert ac1.get_config("addr") in encryption_info[1:]
975-
assert ac2.get_config("addr") in encryption_info[1:]
976-
msg = chat.send_text("encrypted")
977-
assert msg.is_encrypted()
978-
979-
980922
def test_send_first_message_as_long_unicode_with_cr(acfactory, lp):
981923
ac1, ac2 = acfactory.get_online_accounts(2)
982924

@@ -1167,61 +1109,6 @@ def test_dont_show_emails(acfactory, lp):
11671109
assert len(msg.chat.get_messages()) == 3
11681110

11691111

1170-
def test_prefer_encrypt(acfactory, lp):
1171-
"""Test quorum rule for encryption preference in 1:1 and group chat."""
1172-
ac1 = acfactory.new_online_configuring_account(fix_is_chatmail=True)
1173-
ac2 = acfactory.new_online_configuring_account(fix_is_chatmail=True)
1174-
ac3 = acfactory.new_online_configuring_account(fix_is_chatmail=True)
1175-
acfactory.bring_accounts_online()
1176-
ac1.set_config("e2ee_enabled", "0")
1177-
ac2.set_config("e2ee_enabled", "1")
1178-
ac3.set_config("e2ee_enabled", "0")
1179-
1180-
# Make sure we do not send a copy to ourselves. This is to
1181-
# test that we count own preference even when we are not in
1182-
# the recipient list.
1183-
ac1.set_config("bcc_self", "0")
1184-
ac2.set_config("bcc_self", "0")
1185-
ac3.set_config("bcc_self", "0")
1186-
1187-
acfactory.introduce_each_other([ac1, ac2, ac3])
1188-
1189-
lp.sec("ac1: sending message to ac2")
1190-
chat1 = ac1.create_chat(ac2)
1191-
msg1 = chat1.send_text("message1")
1192-
assert not msg1.is_encrypted()
1193-
ac2._evtracker.wait_next_incoming_message()
1194-
1195-
lp.sec("ac2: sending message to ac1")
1196-
chat2 = ac2.create_chat(ac1)
1197-
msg2 = chat2.send_text("message2")
1198-
# Own preference is `Mutual` and we have the peer's key.
1199-
assert msg2.is_encrypted()
1200-
ac1._evtracker.wait_next_incoming_message()
1201-
1202-
lp.sec("ac1: sending message to group chat with ac2 and ac3")
1203-
group = ac1.create_group_chat("hello")
1204-
group.add_contact(ac2)
1205-
group.add_contact(ac3)
1206-
msg3 = group.send_text("message3")
1207-
assert not msg3.is_encrypted()
1208-
ac2._evtracker.wait_next_incoming_message()
1209-
ac3._evtracker.wait_next_incoming_message()
1210-
1211-
lp.sec("ac3: start preferring encryption and inform ac1")
1212-
ac3.set_config("e2ee_enabled", "1")
1213-
chat3 = ac3.create_chat(ac1)
1214-
msg4 = chat3.send_text("message4")
1215-
# Own preference is `Mutual` and we have the peer's key.
1216-
assert msg4.is_encrypted()
1217-
ac1._evtracker.wait_next_incoming_message()
1218-
1219-
lp.sec("ac1: sending another message to group chat with ac2 and ac3")
1220-
msg5 = group.send_text("message5")
1221-
# Majority prefers encryption now
1222-
assert msg5.is_encrypted()
1223-
1224-
12251112
def test_bot(acfactory, lp):
12261113
"""Test that bot messages can be identified as such"""
12271114
ac1, ac2 = acfactory.get_online_accounts(2)
@@ -1250,59 +1137,6 @@ def test_bot(acfactory, lp):
12501137
assert msg_in.is_bot()
12511138

12521139

1253-
def test_quote_encrypted(acfactory, lp):
1254-
"""Test that replies to encrypted messages with quotes are encrypted."""
1255-
ac1, ac2 = acfactory.get_online_accounts(2)
1256-
1257-
lp.sec("ac1: create chat with ac2")
1258-
chat = ac1.create_chat(ac2)
1259-
1260-
lp.sec("sending text message from ac1 to ac2")
1261-
msg1 = chat.send_text("message1")
1262-
assert not msg1.is_encrypted()
1263-
1264-
lp.sec("wait for ac2 to receive message")
1265-
msg2 = ac2._evtracker.wait_next_incoming_message()
1266-
assert msg2.text == "message1"
1267-
assert not msg2.is_encrypted()
1268-
1269-
lp.sec("create new chat with contact and send back (encrypted) message")
1270-
msg2.create_chat().send_text("message-back")
1271-
1272-
lp.sec("wait for ac1 to receive message")
1273-
msg3 = ac1._evtracker.wait_next_incoming_message()
1274-
assert msg3.text == "message-back"
1275-
assert msg3.is_encrypted()
1276-
1277-
lp.sec("ac1: e2ee_enabled=0 and see if reply is encrypted")
1278-
print("ac1: e2ee_enabled={}".format(ac1.get_config("e2ee_enabled")))
1279-
print("ac2: e2ee_enabled={}".format(ac2.get_config("e2ee_enabled")))
1280-
ac1.set_config("e2ee_enabled", "0")
1281-
1282-
for quoted_msg in msg1, msg3:
1283-
# Save the draft with a quote.
1284-
msg_draft = Message.new_empty(ac1, "text")
1285-
msg_draft.set_text("message reply")
1286-
msg_draft.quote = quoted_msg
1287-
chat.set_draft(msg_draft)
1288-
1289-
# Get the draft and send it.
1290-
msg_draft = chat.get_draft()
1291-
chat.send_msg(msg_draft)
1292-
1293-
chat.set_draft(None)
1294-
assert chat.get_draft() is None
1295-
1296-
# Quote should be replaced with "..." if quoted message is encrypted.
1297-
msg_in = ac2._evtracker.wait_next_incoming_message()
1298-
assert msg_in.text == "message reply"
1299-
assert not msg_in.is_encrypted()
1300-
if quoted_msg.is_encrypted():
1301-
assert msg_in.quoted_text == "..."
1302-
else:
1303-
assert msg_in.quoted_text == quoted_msg.text
1304-
1305-
13061140
def test_quote_attachment(tmp_path, acfactory, lp):
13071141
"""Test that replies with an attachment and a quote are received correctly."""
13081142
ac1, ac2 = acfactory.get_online_accounts(2)

src/chat.rs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,8 +1313,7 @@ impl ChatId {
13131313
///
13141314
/// To get more verbose summary for a contact, including its key fingerprint, use [`Contact::get_encrinfo`].
13151315
pub async fn get_encryption_info(self, context: &Context) -> Result<String> {
1316-
let mut ret_mutual = String::new();
1317-
let mut ret_nopreference = String::new();
1316+
let mut ret_available = String::new();
13181317
let mut ret_reset = String::new();
13191318

13201319
for contact_id in get_chat_contacts(context, self)
@@ -1330,8 +1329,9 @@ impl ChatId {
13301329
.filter(|peerstate| peerstate.peek_key(false).is_some())
13311330
.map(|peerstate| peerstate.prefer_encrypt)
13321331
{
1333-
Some(EncryptPreference::Mutual) => ret_mutual += &format!("{addr}\n"),
1334-
Some(EncryptPreference::NoPreference) => ret_nopreference += &format!("{addr}\n"),
1332+
Some(EncryptPreference::Mutual) | Some(EncryptPreference::NoPreference) => {
1333+
ret_available += &format!("{addr}\n")
1334+
}
13351335
Some(EncryptPreference::Reset) | None => ret_reset += &format!("{addr}\n"),
13361336
};
13371337
}
@@ -1343,23 +1343,14 @@ impl ChatId {
13431343
ret.push('\n');
13441344
ret += &ret_reset;
13451345
}
1346-
if !ret_nopreference.is_empty() {
1346+
if !ret_available.is_empty() {
13471347
if !ret.is_empty() {
13481348
ret.push('\n');
13491349
}
13501350
ret += &stock_str::e2e_available(context).await;
13511351
ret.push(':');
13521352
ret.push('\n');
1353-
ret += &ret_nopreference;
1354-
}
1355-
if !ret_mutual.is_empty() {
1356-
if !ret.is_empty() {
1357-
ret.push('\n');
1358-
}
1359-
ret += &stock_str::e2e_preferred(context).await;
1360-
ret.push(':');
1361-
ret.push('\n');
1362-
ret += &ret_mutual;
1353+
ret += &ret_available;
13631354
}
13641355

13651356
Ok(ret.trim().to_string())

src/chat/chat_tests.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,6 @@ async fn test_member_add_remove() -> Result<()> {
299299
let alice = tcm.alice().await;
300300
let bob = tcm.bob().await;
301301

302-
// Disable encryption so we can inspect raw message contents.
303-
alice.set_config(Config::E2eeEnabled, Some("0")).await?;
304-
bob.set_config(Config::E2eeEnabled, Some("0")).await?;
305-
306302
// Create contact for Bob on the Alice side with name "robert".
307303
let alice_bob_contact_id = Contact::create(&alice, "robert", "[email protected]").await?;
308304

@@ -373,9 +369,6 @@ async fn test_parallel_member_remove() -> Result<()> {
373369
let alice = tcm.alice().await;
374370
let bob = tcm.bob().await;
375371

376-
alice.set_config(Config::E2eeEnabled, Some("0")).await?;
377-
bob.set_config(Config::E2eeEnabled, Some("0")).await?;
378-
379372
let alice_bob_contact_id = Contact::create(&alice, "Bob", "[email protected]").await?;
380373
let alice_fiona_contact_id = Contact::create(&alice, "Fiona", "[email protected]").await?;
381374
let alice_claire_contact_id = Contact::create(&alice, "Claire", "[email protected]").await?;
@@ -2677,11 +2670,10 @@ async fn test_chat_get_encryption_info() -> Result<()> {
26772670
"No encryption:\n\
26782671
26792672
\n\
2680-
End-to-end encryption preferred:\n\
2673+
End-to-end encryption available:\n\
26812674
26822675
);
26832676

2684-
bob.set_config(Config::E2eeEnabled, Some("0")).await?;
26852677
send_text_msg(&bob, direct_chat.id, "Hello!".to_string()).await?;
26862678
alice.recv_msg(&bob.pop_sent_msg().await).await;
26872679

src/config/config_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ async fn test_set_config_bool() -> Result<()> {
8686
let t = TestContext::new().await;
8787

8888
// We need some config that defaults to true
89-
let c = Config::E2eeEnabled;
89+
let c = Config::MdnsEnabled;
9090
assert_eq!(t.get_config_bool(c).await?, true);
9191
t.set_config_bool(c, false).await?;
9292
assert_eq!(t.get_config_bool(c).await?, false);

src/configure.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,6 @@ async fn configure(ctx: &Context, param: &EnteredLoginParam) -> Result<Configure
442442
ctx.set_config(Config::MvboxMove, Some("0")).await?;
443443
ctx.set_config(Config::OnlyFetchMvbox, None).await?;
444444
ctx.set_config(Config::ShowEmails, None).await?;
445-
ctx.set_config(Config::E2eeEnabled, Some("1")).await?;
446445
}
447446

448447
let create_mvbox = !is_chatmail;

src/e2ee.rs

Lines changed: 4 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,13 @@ impl EncryptHelper {
5454
peerstates: &[(Option<Peerstate>, String)],
5555
) -> Result<bool> {
5656
let is_chatmail = context.is_chatmail().await?;
57-
let mut prefer_encrypt_count = if self.prefer_encrypt == EncryptPreference::Mutual {
58-
1
59-
} else {
60-
0
61-
};
57+
let mut prefer_encrypt_count = 1;
6258
for (peerstate, addr) in peerstates {
6359
match peerstate {
6460
Some(peerstate) => {
65-
let prefer_encrypt = peerstate.prefer_encrypt;
66-
info!(context, "Peerstate for {addr:?} is {prefer_encrypt}.");
6761
if match peerstate.prefer_encrypt {
68-
EncryptPreference::NoPreference | EncryptPreference::Reset => {
69-
(peerstate.prefer_encrypt != EncryptPreference::Reset || is_chatmail)
70-
&& self.prefer_encrypt == EncryptPreference::Mutual
71-
}
72-
EncryptPreference::Mutual => true,
62+
EncryptPreference::Reset => is_chatmail,
63+
EncryptPreference::NoPreference | EncryptPreference::Mutual => true,
7364
} {
7465
prefer_encrypt_count += 1;
7566
}
@@ -176,6 +167,7 @@ pub async fn ensure_secret_key_exists(context: &Context) -> Result<()> {
176167
mod tests {
177168
use super::*;
178169
use crate::chat::send_text_msg;
170+
use crate::config::Config;
179171
use crate::key::DcKey;
180172
use crate::message::{Message, Viewtype};
181173
use crate::param::Param;
@@ -329,7 +321,6 @@ Sent with my Delta Chat Messenger: https://delta.chat";
329321
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
330322
async fn test_should_encrypt() -> Result<()> {
331323
let t = TestContext::new_alice().await;
332-
assert!(t.get_config_bool(Config::E2eeEnabled).await?);
333324
let encrypt_helper = EncryptHelper::new(&t).await.unwrap();
334325

335326
let ps = new_peerstates(EncryptPreference::NoPreference);
@@ -352,61 +343,6 @@ Sent with my Delta Chat Messenger: https://delta.chat";
352343
Ok(())
353344
}
354345

355-
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
356-
async fn test_should_encrypt_e2ee_disabled() -> Result<()> {
357-
let t = &TestContext::new_alice().await;
358-
t.set_config_bool(Config::E2eeEnabled, false).await?;
359-
let encrypt_helper = EncryptHelper::new(t).await.unwrap();
360-
361-
let ps = new_peerstates(EncryptPreference::NoPreference);
362-
assert!(!encrypt_helper.should_encrypt(t, false, &ps).await?);
363-
364-
let ps = new_peerstates(EncryptPreference::Reset);
365-
assert!(encrypt_helper.should_encrypt(t, true, &ps).await?);
366-
367-
let mut ps = new_peerstates(EncryptPreference::Mutual);
368-
// Own preference is `NoPreference` and there's no majority with `Mutual`.
369-
assert!(!encrypt_helper.should_encrypt(t, false, &ps).await?);
370-
// Now the majority wants to encrypt. Let's encrypt, anyway there are other cases when we
371-
// can't send unencrypted, e.g. protected groups.
372-
ps.push(ps[0].clone());
373-
assert!(encrypt_helper.should_encrypt(t, false, &ps).await?);
374-
375-
// Test with missing peerstate.
376-
let ps = vec![(None, "[email protected]".to_string())];
377-
assert!(encrypt_helper.should_encrypt(t, true, &ps).await.is_err());
378-
Ok(())
379-
}
380-
381-
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
382-
async fn test_chatmail_prefers_to_encrypt() -> Result<()> {
383-
let mut tcm = TestContextManager::new();
384-
let alice = &tcm.alice().await;
385-
let bob = &tcm.bob().await;
386-
bob.set_config_bool(Config::IsChatmail, true).await?;
387-
388-
let bob_chat_id = tcm
389-
.send_recv_accept(alice, bob, "Hello from DC")
390-
.await
391-
.chat_id;
392-
receive_imf(
393-
bob,
394-
b"From: [email protected]\n\
395-
396-
Message-ID: <[email protected]>\n\
397-
Date: Sun, 22 Mar 3000 22:37:58 +0000\n\
398-
\n\
399-
Hello from another MUA\n",
400-
false,
401-
)
402-
.await?;
403-
send_text_msg(bob, bob_chat_id, "hi".to_string()).await?;
404-
let sent_msg = bob.pop_sent_msg().await;
405-
let msg = Message::load_from_db(bob, sent_msg.sender_msg_id).await?;
406-
assert!(msg.get_showpadlock());
407-
Ok(())
408-
}
409-
410346
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
411347
async fn test_chatmail_can_send_unencrypted() -> Result<()> {
412348
let mut tcm = TestContextManager::new();

0 commit comments

Comments
 (0)