Merge pull request #1314 from deltachat/fix-secure-join

ignore handshake messages seen from another device
This commit is contained in:
bjoern
2020-03-28 10:28:55 +01:00
committed by GitHub
2 changed files with 57 additions and 7 deletions

View File

@@ -17,7 +17,7 @@ use crate::message::{self, MessageState, MessengerMessage, MsgId};
use crate::mimeparser::*;
use crate::param::*;
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::stock::StockMessage;
use crate::{contact, location};
@@ -340,11 +340,9 @@ fn add_parts(
};
to_id = DC_CONTACT_ID_SELF;
// handshake messages must be processed _before_ chats are created
// (eg. contacs may be marked as verified)
// handshake may mark contacts as verified and must be processed before chats are created
if mime_parser.get(HeaderDef::SecureJoin).is_some() {
// avoid discarding by show_emails setting
msgrmsg = MessengerMessage::Yes;
msgrmsg = MessengerMessage::Yes; // avoid discarding by show_emails setting
*chat_id = ChatId::new(0);
allow_creation = true;
match handle_securejoin_handshake(context, mime_parser, from_id) {
@@ -358,8 +356,7 @@ fn add_parts(
state = MessageState::InSeen;
}
Ok(securejoin::HandshakeMessage::Propagate) => {
// Message will still be processed as "member
// added" or similar system message.
// process messages as "member added" normally
}
Err(err) => {
*hidden = true;
@@ -476,6 +473,27 @@ fn add_parts(
// We cannot recreate other states (read, error).
state = MessageState::OutDelivered;
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 chat_id.is_unset() {
let (new_chat_id, new_chat_id_blocked) = create_or_lookup_group(

View File

@@ -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) {
let contact_id: u32 = chat_id_2_contact_id(context, contact_chat_id);
let contact = Contact::get_by_id(context, contact_id);