If we use modules (which are actually namespaces), we can use shorter names. Another approach is to
only use modules for internal code incapsulation and use full names like deltachat-ffi does.
Create unprotected group in test_create_protected_grp_multidev
The test is renamed accordingly.
SystemMessage::ChatE2ee is added in encrypted groups
regardless of whether they are protected or not.
Previously new encrypted unprotected groups
had no message saying that messages are end-to-end encrypted
at all.
Quoting @adbenitez:
> I have been using the SecurejoinInviterProgress event to show a
welcome message when user scan the QR/link of the bot (== starts a chat
with the bot)
> but this have a big problem: in that event all you know is that a
contact completed the secure-join process, you don't know if it was via
certain 1:1 invite link or a group invitation, then a group-invite bot
would send you a help message in 1:1 every time you join a group with it
Since it's easy enough to add this information to the
SecurejoinInviterProgress event, I wrote a PR to do so.
this PR adds a info message "messages are end-to-end-encrypted" also for
chats created by eg. vcards. by the removal of lock icons, this is a
good place to hint for that in addition; this is also what eg. whatsapp
and others are doing
the wording itself is tweaked at
https://github.com/deltachat/deltachat-android/pull/3817 (and there is
also the rough idea to make the message a little more outstanding, by
some more dedicated colors)
~~did not test in practise, if this leads to double "e2ee info messages"
on secure join, tests look good, however.~~ EDIT: did lots of practise
tests meanwhile :)
most of the changes in this PR are about test ...
ftr, in another PR, after 2.0 reeases, there could probably quite some
code cleanup wrt set-protection, protection-disabled etc.
---------
Co-authored-by: Hocuri <hocuri@gmx.de>
This change introduces a new type of contacts
identified by their public key fingerprint
rather than an e-mail address.
Encrypted chats now stay encrypted
and unencrypted chats stay unencrypted.
For example, 1:1 chats with key-contacts
are encrypted and 1:1 chats with address-contacts
are unencrypted.
Groups that have a group ID are encrypted
and can only contain key-contacts
while groups that don't have a group ID ("adhoc groups")
are unencrypted and can only contain address-contacts.
JSON-RPC API `reset_contact_encryption` is removed.
Python API `Contact.reset_encryption` is removed.
"Group tracking plugin" in legacy Python API was removed because it
relied on parsing email addresses from system messages with regexps.
Co-authored-by: Hocuri <hocuri@gmx.de>
Co-authored-by: iequidoo <dgreshilov@gmail.com>
Co-authored-by: B. Petersen <r10s@b44t.com>
Revert the biggest part of https://github.com/chatmail/core/pull/6722/
in order to fix#6816. Reopens
https://github.com/chatmail/core/issues/6706.
Rationale for reverting instead of fixing is that it's not trivial to
implement "if the chat is encrypted, can_send() returns true": When
sending a message, in order to check whether to encrypt, we load all
peerstates and check whether all of them can be encrypted to
(`should_encrypt()`). We could do this in `can_send()`, but this would
make it quite slow for groups. With multi-transport, the ways of
checking whether to encrypt will be different, so in order not to do
unnecessary work now, this PR just revert parts of
[https://github.com/chatmail/core/pull/6722/](https://github.com/chatmail/core/pull/6817#),
so that we can make things work nicely when multi-transport is merged.
As a quick mitigation, we could increase the timeout from 15s to
something like 1 minute or 1 day: Long enough that usually securejoin
will finish before, but short enough that it's possible to send to old
chats that had a failed securejoin long in the past.
In the `test` cfg, introduce `MimeMessage::headers_removed` hash set and `header_exists()` function
returning whether the header exists in any part of the parsed message. `get_header()` shouldn't be
used in tests for checking absense of headers because it returns `None` for removed ("ignored")
headers.
instead of showing addresses in info message, provide an API to get the
contact-id.
UI can then make the info message tappable and open the contact profile
in scope
the corresponding iOS PR - incl. **screencast** - is at
https://github.com/deltachat/deltachat-ios/pull/2652 ; jsonrpc can come
in a subsequent PR when things are settled on android/ios
the number of parameters in `add_info_msg_with_cmd` gets bigger and
bigger, however, i did not want to refactor this in this PR. it is also
not really adding complexity
closes#6702
---------
Co-authored-by: link2xt <link2xt@testrun.org>
Co-authored-by: Hocuri <hocuri@gmx.de>
vc-request is an unencrypted message
that Bob sends when he does not have Alice's key.
It also does not contain
Bob's avatar and name,
so the contact has only the email address
at this point and it is too early
to show it.
SecureJoin and importing a vCard are the primary
ways we want to support for creating contacts.
Typing in an email address and relying on Autocrypt
results in sending the first message unencrypted
and we want to clearly separate unencrypted and encrypted
chats in the future.
To make the tests more stable, we set up test contacts
with vCards as this always immediately
results in creating a single encrypted chat
and this is not going to change.
This implements new group consistency algorithm described in
<https://github.com/deltachat/deltachat-core-rust/issues/6401>
New `Chat-Group-Member-Timestamps` header is added
to send timestamps of member additions and removals.
Member is part of the chat if its addition timestamp
is greater or equal to the removal timestamp.
Received messages shouldn't mingle with just sent ones and appear somewhere in the middle of the
chat, so we go after the newest non fresh message.
But if a received outgoing message is older than some `InSeen` message, better sort the received
message purely by timestamp (this is an heuristic in order not to break the Gmail-like case
simulated by `verified_chats::test_old_message_4()`). We could place the received message just
before that `InSeen` message, but anyway the user may not notice it.
At least this fixes outgoing messages sorting for shared accounts where messages from other devices
should be sorted the same way as incoming ones.
The "Cannot establish guaranteed end-to-end encryption with ..." info
message can have lots of causes, and it happened twice to us now that it
took us some time to figure out which one it is.
So, include some more detail in the info message by simply adding the
non-translated error message in parantheses.
If we want to put in some more effort for nicer error messages, we
could:
- Introduce one new translated string "Cannot establish guaranteed
end-to-end encryption with …. Cause: %2$s" or similar (and remove the
old stock string)
- And/Or: Introduce new translated strings for all the possible errors
- And/Or: Maybe reword it in order to account better for the case that
the chat already is marked as g-e2ee, or use a different wording
(because if the chat is marked as g-e2ee then it might be nice to notify
the user that something may have gone wrong, but it's still working,
just that maybe the other side doesn't have us verified now)

This protects Bob (the joiner) of sending unexpected-unencrypted messages during an otherwise nicely
running SecureJoin.
If things get stuck, however, we do not want to block communication -- the chat is just
opportunistic as usual, but that needs to be communicated:
1. If Bob's chat with Alice is `Unprotected` and a SecureJoin is started, then add info-message
"Establishing guaranteed end-to-end encryption, please wait..." and let `Chat::can_send()` return
`false`.
2. Once the info-message "Messages are guaranteed to be e2ee from now on" is added, let
`Chat::can_send()` return `true`.
3. If after SECUREJOIN_WAIT_TIMEOUT seconds `2.` did not happen, add another info-message "Could not
yet establish guaranteed end-to-end encryption but you may already send a message" and also let
`Chat::can_send()` return `true`.
Both `2.` and `3.` require the event `ChatModified` being sent out so that UI pick up the change wrt
`Chat::can_send()` (this is the same way how groups become updated wrt `can_send()` changes).
SECUREJOIN_WAIT_TIMEOUT should be 10-20 seconds so that we are reasonably sure that the app remains
active and receiving also on mobile devices. If the app is killed during this time then we may need
to do step 3 for any pending Bob-join chats (right now, Bob can only join one chat at a time).
Secure-Join-Group is only expected by old core in vg-request-with-auth.
There is no reason to leak group ID in unencrypted vg-request.
Besides that, Secure-Join-Group is deprecated
as Alice knows Group ID corresponding to the auth code,
so the header can be removed completely eventually.
Mark 1:1 chat as verified as soon as Alice is forward-verified
so Bob can already start sending Chat-Verified headers.
This way Alice and Bob can scan each other's QR codes
and even if all Secure-Join headers are dropped from the network,
still get forward verifications via QR-code scans
and backward verifications via Chat-Verified messages in 1:1 chat.
As per the comment in `receive_imf.rs`, `chat.protected` must be maintained regardless of the
`Config::VerifiedOneOnOneChats`. The only thing that mustn't be done if `VerifiedOneOnOneChats` is
unset (i.e. for non-supporting UIs) is marking chats as "protection broken" because this needs
showing the corresponding dialog to a user.
Before in some places it was correctly calculated by passing the "sent" timestamp to
`calc_sort_timestamp()`, but in other places just the system time was used. In some complex
scenarios like #5088 (restoration of a backup made before a contact verification) it led to wrong
sort timestamps of protection messages and also messages following by them.
But to reduce number of args passed to functions needing to calculate the sort timestamp, add
message timestamps to `struct MimeMessage` which is anyway passed everywhere.