From b586aebbac20ea03509e42e54f1632d654ea968d Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sat, 12 Feb 2022 17:18:03 +0100 Subject: Calls: Fix OMEMO in group calls --- .../omemo/src/dtls_srtp_verification_draft.vala | 64 +++++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) (limited to 'plugins/omemo') diff --git a/plugins/omemo/src/dtls_srtp_verification_draft.vala b/plugins/omemo/src/dtls_srtp_verification_draft.vala index 577c77e7..cc775977 100644 --- a/plugins/omemo/src/dtls_srtp_verification_draft.vala +++ b/plugins/omemo/src/dtls_srtp_verification_draft.vala @@ -11,6 +11,7 @@ namespace Dino.Plugins.Omemo.DtlsSrtpVerificationDraft { private VerificationSendListener send_listener = new VerificationSendListener(); private HashMap device_id_by_jingle_sid = new HashMap(); + private HashMap device_id_by_muji_member = new HashMap(); private HashMap> content_names_by_jingle_sid = new HashMap>(); private void on_preprocess_incoming_iq_set_get(XmppStream stream, Xmpp.Iq.Stanza iq) { @@ -88,8 +89,26 @@ namespace Dino.Plugins.Omemo.DtlsSrtpVerificationDraft { StanzaNode? jingle_node = iq.stanza.get_subnode("jingle", Xep.Jingle.NS_URI); if (jingle_node == null) return; + int device_id = -1; string? sid = jingle_node.get_attribute("sid", Xep.Jingle.NS_URI); - if (sid == null || !device_id_by_jingle_sid.has_key(sid)) return; + if (sid != null && device_id_by_jingle_sid.has_key(sid)) { + device_id = device_id_by_jingle_sid[sid]; + } + + StanzaNode? muji_node = jingle_node.get_subnode("muji", Xep.Muji.NS_URI); + if (muji_node != null) { + string muji_room = muji_node.get_attribute("room"); + try { + Jid muji_jid = new Jid(muji_room); + if (device_id_by_muji_member.has_key(@"$(muji_jid.bare_jid)/$(iq.to)")) { + device_id = device_id_by_muji_member[@"$(muji_jid.bare_jid)/$(iq.to)"]; + } + } catch (InvalidJidError e) { + // Ignore + } + } + + if (device_id == -1) return; Gee.List content_nodes = jingle_node.get_subnodes("content", Xep.Jingle.NS_URI); if (content_nodes.size == 0) return; @@ -105,7 +124,7 @@ namespace Dino.Plugins.Omemo.DtlsSrtpVerificationDraft { try { Xep.Omemo.OmemoEncryptor encryptor = stream.get_module(Xep.Omemo.OmemoEncryptor.IDENTITY); Xep.Omemo.EncryptionData enc_data = encryptor.encrypt_plaintext(fingerprint); - encryptor.encrypt_key(enc_data, iq.to.bare_jid, device_id_by_jingle_sid[sid]); + encryptor.encrypt_key(enc_data, iq.to.bare_jid, device_id); encrypted_node = enc_data.get_encrypted_node(); } catch (Error e) { warning("Error while OMEMO-encrypting call keys: %s", e.message); @@ -155,12 +174,52 @@ namespace Dino.Plugins.Omemo.DtlsSrtpVerificationDraft { } } + private void on_pre_send_presence_stanza(XmppStream stream, Presence.Stanza presence) { + StanzaNode? muji_node = presence.stanza.get_subnode("muji", Xep.Muji.NS_URI); + if (muji_node == null) return; + + StanzaNode device_node = new StanzaNode.build("device", NS_URI).add_self_xmlns() + .put_attribute("id", stream.get_module(Omemo.StreamModule.IDENTITY).store.local_registration_id.to_string()); + muji_node.put_node(device_node); + } + + private void on_received_available(XmppStream stream, Presence.Stanza presence) { + StanzaNode? muji_node = presence.stanza.get_subnode("muji", Xep.Muji.NS_URI); + if (muji_node == null) return; + + StanzaNode? device_node = muji_node.get_subnode("device", NS_URI); + if (device_node == null) return; + + int device_id = device_node.get_attribute_int("id", -1); + if (device_id == -1) return; + + StanzaNode? muc_x_node = presence.stanza.get_subnode("x", "http://jabber.org/protocol/muc#user"); + if (muc_x_node == null) return; + + StanzaNode? item_node = muc_x_node.get_subnode("item"); + if (item_node == null) return; + + Jid? real_jid = null; + try { + string jid_attribute = item_node.get_attribute("jid"); + if (jid_attribute == null) return; + real_jid = new Jid(jid_attribute); + } catch (InvalidJidError e) { + // Ignore + return; + } + + device_id_by_muji_member[@"$(presence.from.bare_jid)/$(real_jid)"] = device_id; + } + public override void attach(XmppStream stream) { stream.get_module(Xmpp.MessageModule.IDENTITY).received_message.connect(on_message_received); stream.get_module(Xmpp.MessageModule.IDENTITY).send_pipeline.connect(send_listener); stream.get_module(Xmpp.Iq.Module.IDENTITY).preprocess_incoming_iq_set_get.connect(on_preprocess_incoming_iq_set_get); stream.get_module(Xmpp.Iq.Module.IDENTITY).preprocess_outgoing_iq_set_get.connect(on_preprocess_outgoing_iq_set_get); stream.get_module(Xep.Jingle.Module.IDENTITY).session_initiate_received.connect(on_session_initiate_received); + stream.get_module(Xmpp.Presence.Module.IDENTITY).pre_send_presence_stanza.connect(on_pre_send_presence_stanza); + stream.get_module(Xmpp.Presence.Module.IDENTITY).received_available.connect(on_received_available); } public override void detach(XmppStream stream) { @@ -169,6 +228,7 @@ namespace Dino.Plugins.Omemo.DtlsSrtpVerificationDraft { stream.get_module(Xmpp.Iq.Module.IDENTITY).preprocess_incoming_iq_set_get.disconnect(on_preprocess_incoming_iq_set_get); stream.get_module(Xmpp.Iq.Module.IDENTITY).preprocess_outgoing_iq_set_get.disconnect(on_preprocess_outgoing_iq_set_get); stream.get_module(Xep.Jingle.Module.IDENTITY).session_initiate_received.disconnect(on_session_initiate_received); + stream.get_module(Xmpp.Presence.Module.IDENTITY).received_available.disconnect(on_received_available); } public override string get_ns() { return NS_URI; } -- cgit v1.2.3-54-g00ecf