mirror of
https://github.com/chatmail/core.git
synced 2026-05-01 20:36:31 +03:00
Merge pull request #1314 from deltachat/fix-secure-join
ignore handshake messages seen from another device
This commit is contained in:
@@ -17,7 +17,7 @@ use crate::message::{self, MessageState, MessengerMessage, MsgId};
|
|||||||
use crate::mimeparser::*;
|
use crate::mimeparser::*;
|
||||||
use crate::param::*;
|
use crate::param::*;
|
||||||
use crate::peerstate::*;
|
use crate::peerstate::*;
|
||||||
use crate::securejoin::{self, handle_securejoin_handshake};
|
use crate::securejoin::{self, handle_securejoin_handshake, observe_securejoin_on_other_device};
|
||||||
use crate::sql;
|
use crate::sql;
|
||||||
use crate::stock::StockMessage;
|
use crate::stock::StockMessage;
|
||||||
use crate::{contact, location};
|
use crate::{contact, location};
|
||||||
@@ -340,11 +340,9 @@ fn add_parts(
|
|||||||
};
|
};
|
||||||
to_id = DC_CONTACT_ID_SELF;
|
to_id = DC_CONTACT_ID_SELF;
|
||||||
|
|
||||||
// handshake messages must be processed _before_ chats are created
|
// handshake may mark contacts as verified and must be processed before chats are created
|
||||||
// (eg. contacs may be marked as verified)
|
|
||||||
if mime_parser.get(HeaderDef::SecureJoin).is_some() {
|
if mime_parser.get(HeaderDef::SecureJoin).is_some() {
|
||||||
// avoid discarding by show_emails setting
|
msgrmsg = MessengerMessage::Yes; // avoid discarding by show_emails setting
|
||||||
msgrmsg = MessengerMessage::Yes;
|
|
||||||
*chat_id = ChatId::new(0);
|
*chat_id = ChatId::new(0);
|
||||||
allow_creation = true;
|
allow_creation = true;
|
||||||
match handle_securejoin_handshake(context, mime_parser, from_id) {
|
match handle_securejoin_handshake(context, mime_parser, from_id) {
|
||||||
@@ -358,8 +356,7 @@ fn add_parts(
|
|||||||
state = MessageState::InSeen;
|
state = MessageState::InSeen;
|
||||||
}
|
}
|
||||||
Ok(securejoin::HandshakeMessage::Propagate) => {
|
Ok(securejoin::HandshakeMessage::Propagate) => {
|
||||||
// Message will still be processed as "member
|
// process messages as "member added" normally
|
||||||
// added" or similar system message.
|
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
*hidden = true;
|
*hidden = true;
|
||||||
@@ -476,6 +473,27 @@ fn add_parts(
|
|||||||
// We cannot recreate other states (read, error).
|
// We cannot recreate other states (read, error).
|
||||||
state = MessageState::OutDelivered;
|
state = MessageState::OutDelivered;
|
||||||
to_id = to_ids.get_index(0).cloned().unwrap_or_default();
|
to_id = to_ids.get_index(0).cloned().unwrap_or_default();
|
||||||
|
|
||||||
|
// handshake may mark contacts as verified and must be processed before chats are created
|
||||||
|
if mime_parser.get(HeaderDef::SecureJoin).is_some() {
|
||||||
|
msgrmsg = MessengerMessage::Yes; // avoid discarding by show_emails setting
|
||||||
|
*chat_id = ChatId::new(0);
|
||||||
|
allow_creation = true;
|
||||||
|
match observe_securejoin_on_other_device(context, mime_parser, to_id) {
|
||||||
|
Ok(securejoin::HandshakeMessage::Done)
|
||||||
|
| Ok(securejoin::HandshakeMessage::Ignore) => {
|
||||||
|
*hidden = true;
|
||||||
|
}
|
||||||
|
Ok(securejoin::HandshakeMessage::Propagate) => {
|
||||||
|
// process messages as "member added" normally
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
*hidden = true;
|
||||||
|
error!(context, "Error in Secure-Join watching: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !to_ids.is_empty() {
|
if !to_ids.is_empty() {
|
||||||
if chat_id.is_unset() {
|
if chat_id.is_unset() {
|
||||||
let (new_chat_id, new_chat_id_blocked) = create_or_lookup_group(
|
let (new_chat_id, new_chat_id_blocked) = create_or_lookup_group(
|
||||||
|
|||||||
@@ -770,6 +770,38 @@ pub(crate) fn handle_securejoin_handshake(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// observe_securejoin_on_other_device() must be called when a self-sent securejoin message is seen.
|
||||||
|
/// currently, the message is only ignored, in the future,
|
||||||
|
/// we may mark peers as verified accross devices:
|
||||||
|
///
|
||||||
|
/// in a multi-device-setup, there may be other devices that "see" the handshake messages.
|
||||||
|
/// if the seen messages seen are self-sent messages encrypted+signed correctly with our key,
|
||||||
|
/// we can make some conclusions of it:
|
||||||
|
///
|
||||||
|
/// - if we see the self-sent-message vg-member-added/vc-contact-confirm,
|
||||||
|
/// we know that we're an inviter-observer.
|
||||||
|
/// the inviting device has marked a peer as verified on vg-request-with-auth/vc-request-with-auth
|
||||||
|
/// before sending vg-member-added/vc-contact-confirm - so, if we observe vg-member-added/vc-contact-confirm,
|
||||||
|
/// we can mark the peer as verified as well.
|
||||||
|
///
|
||||||
|
/// - if we see the self-sent-message vg-member-added-received
|
||||||
|
/// we know that we're an joiner-observer.
|
||||||
|
/// the joining device has marked the peer as verified on vg-member-added/vc-contact-confirm
|
||||||
|
/// before sending vg-member-added-received - so, if we observe vg-member-added-received,
|
||||||
|
/// we can mark the peer as verified as well.
|
||||||
|
///
|
||||||
|
/// to make this work, (a) some messages must not be deleted,
|
||||||
|
/// (b) we need a vc-contact-confirm-received message if bcc_self is set,
|
||||||
|
/// (c) we should make sure, we do not only rely on the unencrypted To:-header for identifying the peer
|
||||||
|
/// (in handle_securejoin_handshake() we have the oob information for that)
|
||||||
|
pub(crate) fn observe_securejoin_on_other_device(
|
||||||
|
_context: &Context,
|
||||||
|
_mime_message: &MimeMessage,
|
||||||
|
_contact_id: u32,
|
||||||
|
) -> Result<HandshakeMessage, HandshakeError> {
|
||||||
|
Ok(HandshakeMessage::Ignore)
|
||||||
|
}
|
||||||
|
|
||||||
fn secure_connection_established(context: &Context, contact_chat_id: ChatId) {
|
fn secure_connection_established(context: &Context, contact_chat_id: ChatId) {
|
||||||
let contact_id: u32 = chat_id_2_contact_id(context, contact_chat_id);
|
let contact_id: u32 = chat_id_2_contact_id(context, contact_chat_id);
|
||||||
let contact = Contact::get_by_id(context, contact_id);
|
let contact = Contact::get_by_id(context, contact_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user