changeset 2744:e6716d90c2fe

plugin XEP-0384: various bug fixes: - fixed trust management on message sending, when trusts are missing - retrieve identiy keys when trust has not been set yet - added our own device when it is found missing on PEP notification - mark message as trusted when suitable
author Goffi <goffi@goffi.org>
date Thu, 03 Jan 2019 21:04:55 +0100
parents da59ff099b32
children 3ee396b2ecf3
files sat/plugins/plugin_xep_0384.py
diffstat 1 files changed, 40 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0384.py	Thu Jan 03 21:00:00 2019 +0100
+++ b/sat/plugins/plugin_xep_0384.py	Thu Jan 03 21:04:55 2019 +0100
@@ -294,7 +294,7 @@
 
     @classmethod
     def create(cls, client, storage, my_device_id = None):
-        omemo_session_p = client._xep_0384_session = omemo.SessionManager.create(
+        omemo_session_p = omemo.SessionManager.create(
             storage,
             SatOTPKPolicy,
             omemo_backend,
@@ -448,16 +448,38 @@
         """
         # we need entity_jid xor trust_data
         assert entity_jid and not trust_data or not entity_jid and trust_data
-        if entity_jid.resource:
+        if entity_jid and entity_jid.resource:
             raise ValueError(u"A bare jid is expected")
 
         session = client._xep_0384_session
 
         if trust_data is None:
+            cache = client._xep_0384_cache.setdefault(entity_jid, {})
             trust_data = {}
             trust_session_data = yield session.getTrustForJID(entity_jid)
             bare_jid_s = entity_jid.userhost()
             for device_id, trust_info in trust_session_data['active'].iteritems():
+                if trust_info is None:
+                    # device has never been (un)trusted, we have to retrieve its
+                    # fingerprint (i.e. identity key or "ik") through public bundle
+                    if device_id not in cache:
+                        bundles, missing = yield self.getBundles(client,
+                                                                 entity_jid,
+                                                                 [device_id])
+                        if device_id not in bundles:
+                            log.warning(_(
+                                u"Can't find bundle for device {device_id} of user "
+                                u"{bare_jid}, ignoring").format(device_id=device_id,
+                                                                bare_jid=bare_jid_s))
+                            continue
+                        cache[device_id] = bundles[device_id]
+                    # TODO: replace False below by None when undecided
+                    #       trusts are handled
+                    trust_info = {
+                        u"key": cache[device_id].ik,
+                        u"trusted": False
+                    }
+
                 ik = trust_info["key"]
                 trust_id = unicode(hash((bare_jid_s, device_id, ik)))
                 trust_data[trust_id] = {
@@ -788,6 +810,14 @@
                         u"devices list"))
                     existing_devices = devices - bundles_not_found
                     yield self.setDevices(client, existing_devices)
+        # we check that our device has not been removed from the list
+        if entity == client.jid.userhostJID():
+            own_device = client._xep_0384_device_id
+            if own_device not in devices:
+                log.warning(_(u"Our own device is missing from devices list, fixing it"))
+                devices.add(own_device)
+                yield self.setDevices(client, devices)
+
 
     ## triggers
 
@@ -814,12 +844,13 @@
 
         if untrusted:
             trust_data = {}
-            for device_id, data in untrusted.iteritems():
-                trust_data[u'jid'] = jid.JID(data.bare_jid)
-                trust_data[u'device'] = data.device
-                trust_data[u'ik'] = data.ik
+            for trust_id, data in untrusted.iteritems():
+                trust_data[trust_id] = {
+                    'jid': jid.JID(data.bare_jid),
+                    'device':  data.device,
+                    'ik': data.ik}
 
-            xmlui = yield self.getTrustUI(client, trust_data, submit_id=u"")
+            xmlui = yield self.getTrustUI(client, trust_data=trust_data, submit_id=u"")
 
             answer = yield xml_tools.deferXMLUI(
                 self.host,
@@ -954,6 +985,8 @@
                 post_treat.addCallback(client.encryption.markAsUntrusted)
                 kwargs['allow_untrusted'] = True
                 plaintext = yield omemo_session.decryptMessage(**kwargs)
+            else:
+                post_treat.addCallback(client.encryption.markAsTrusted)
         except Exception as e:
             log.warning(_(u"Can't decrypt message: {reason}\n{xml}").format(
                 reason=e, xml=message_elt.toXml()))