comparison sat/plugins/plugin_xep_0384.py @ 3084:ffcdd93b61fa

plugin XEP-0384: specific warning on missing omemo-backend-signal + fixed encoding following Python 3 port
author Goffi <goffi@goffi.org>
date Sat, 07 Dec 2019 11:30:56 +0100
parents ab2696e34d29
children c048fc192739
comparison
equal deleted inserted replaced
3083:3c924cb207d9 3084:ffcdd93b61fa
19 19
20 from sat.core.i18n import _, D_ 20 from sat.core.i18n import _, D_
21 from sat.core.constants import Const as C 21 from sat.core.constants import Const as C
22 from sat.core.log import getLogger 22 from sat.core.log import getLogger
23 from sat.core import exceptions 23 from sat.core import exceptions
24 from omemo import exceptions as omemo_excpt
25 from twisted.internet import defer 24 from twisted.internet import defer
26 from twisted.words.xish import domish 25 from twisted.words.xish import domish
27 from twisted.words.protocols.jabber import jid 26 from twisted.words.protocols.jabber import jid
28 from twisted.words.protocols.jabber import error 27 from twisted.words.protocols.jabber import error
29 from sat.memory import persistent 28 from sat.memory import persistent
32 import logging 31 import logging
33 import random 32 import random
34 import base64 33 import base64
35 try: 34 try:
36 import omemo 35 import omemo
36 from omemo import exceptions as omemo_excpt
37 from omemo.extendedpublicbundle import ExtendedPublicBundle 37 from omemo.extendedpublicbundle import ExtendedPublicBundle
38 from omemo_backend_signal import BACKEND as omemo_backend 38 except ImportError:
39 # from omemo import wireformat
40 except ImportError as e:
41 raise exceptions.MissingModule( 39 raise exceptions.MissingModule(
42 'Missing module omemo, please download/install it. You can use ' 40 'Missing module omemo, please download/install it. You can use '
43 '"pip install omemo"' 41 '"pip install omemo"'
42 )
43 try:
44 from omemo_backend_signal import BACKEND as omemo_backend
45 except ImportError:
46 raise exceptions.MissingModule(
47 'Missing module omemo-backend-signal, please download/install it. You can use '
48 '"pip install omemo-backend-signal"'
44 ) 49 )
45 50
46 log = getLogger(__name__) 51 log = getLogger(__name__)
47 52
48 PLUGIN_INFO = { 53 PLUGIN_INFO = {
333 bare_jids = [e.userhost() for e in bare_jids] 338 bare_jids = [e.userhost() for e in bare_jids]
334 if bundles is not None: 339 if bundles is not None:
335 bundles = {e.userhost(): v for e, v in bundles.items()} 340 bundles = {e.userhost(): v for e, v in bundles.items()}
336 encrypt_mess_p = self._session.encryptMessage( 341 encrypt_mess_p = self._session.encryptMessage(
337 bare_jids=bare_jids, 342 bare_jids=bare_jids,
338 plaintext=message.encode('utf-8'), 343 plaintext=message.encode(),
339 bundles=bundles, 344 bundles=bundles,
340 expect_problems=expect_problems) 345 expect_problems=expect_problems)
341 return promise2Deferred(encrypt_mess_p) 346 return promise2Deferred(encrypt_mess_p)
342 347
343 def decryptMessage(self, bare_jid, device, iv, message, is_pre_key_message, 348 def decryptMessage(self, bare_jid, device, iv, message, is_pre_key_message,
423 data["ik"]) 428 data["ik"])
424 if expect_problems is not None: 429 if expect_problems is not None:
425 expect_problems.setdefault(data.bare_jid, set()).add(data.device) 430 expect_problems.setdefault(data.bare_jid, set()).add(data.device)
426 defer.returnValue({}) 431 defer.returnValue({})
427 432
428
429
430 @defer.inlineCallbacks 433 @defer.inlineCallbacks
431 def getTrustUI(self, client, entity_jid=None, trust_data=None, submit_id=None): 434 def getTrustUI(self, client, entity_jid=None, trust_data=None, submit_id=None):
432 """Generate a XMLUI to manage trust 435 """Generate a XMLUI to manage trust
433 436
434 @param entity_jid(None, jid.JID): jid of entity to manage 437 @param entity_jid(None, jid.JID): jid of entity to manage
510 513
511 xmlui.changeContainer("label") 514 xmlui.changeContainer("label")
512 xmlui.addLabel(D_("This device ID")) 515 xmlui.addLabel(D_("This device ID"))
513 xmlui.addText(str(client._xep_0384_device_id)) 516 xmlui.addText(str(client._xep_0384_device_id))
514 xmlui.addLabel(D_("This device fingerprint")) 517 xmlui.addLabel(D_("This device fingerprint"))
515 ik_hex = session.public_bundle.ik.encode('hex').upper() 518 ik_hex = session.public_bundle.ik.hex().upper()
516 fp_human = ' '.join([ik_hex[i:i+8] for i in range(0, len(ik_hex), 8)]) 519 fp_human = ' '.join([ik_hex[i:i+8] for i in range(0, len(ik_hex), 8)])
517 xmlui.addText(fp_human) 520 xmlui.addText(fp_human)
518 xmlui.addEmpty() 521 xmlui.addEmpty()
519 xmlui.addEmpty() 522 xmlui.addEmpty()
520 523
523 xmlui.addLabel(D_("Contact")) 526 xmlui.addLabel(D_("Contact"))
524 xmlui.addJid(data['jid']) 527 xmlui.addJid(data['jid'])
525 xmlui.addLabel(D_("Device ID")) 528 xmlui.addLabel(D_("Device ID"))
526 xmlui.addText(str(data['device'])) 529 xmlui.addText(str(data['device']))
527 xmlui.addLabel(D_("Fingerprint")) 530 xmlui.addLabel(D_("Fingerprint"))
528 ik_hex = data['ik'].encode('hex').upper() 531 ik_hex = data['ik'].hex().upper()
529 fp_human = ' '.join([ik_hex[i:i+8] for i in range(0, len(ik_hex), 8)]) 532 fp_human = ' '.join([ik_hex[i:i+8] for i in range(0, len(ik_hex), 8)])
530 xmlui.addText(fp_human) 533 xmlui.addText(fp_human)
531 xmlui.addLabel(D_("Trust this device?")) 534 xmlui.addLabel(D_("Trust this device?"))
532 xmlui.addBool("trust_{}".format(trust_id), 535 xmlui.addBool("trust_{}".format(trust_id),
533 value=C.boolConst(data.get('trusted', False))) 536 value=C.boolConst(data.get('trusted', False)))
902 loop_idx += 1 905 loop_idx += 1
903 else: 906 else:
904 break 907 break
905 except Exception as e: 908 except Exception as e:
906 msg = _("Can't encrypt message for {entity}: {reason}".format( 909 msg = _("Can't encrypt message for {entity}: {reason}".format(
907 entity=entity_bare_jid.full(), reason=str(e).decode('utf-8', 'replace'))) 910 entity=entity_bare_jid.full(), reason=e))
908 log.warning(msg) 911 log.warning(msg)
909 extra = {C.MESS_EXTRA_INFO: C.EXTRA_INFO_ENCR_ERR} 912 extra = {C.MESS_EXTRA_INFO: C.EXTRA_INFO_ENCR_ERR}
910 client.feedback(entity_bare_jid, msg, extra) 913 client.feedback(entity_bare_jid, msg, extra)
911 raise e 914 raise e
912 915
957 except StopIteration: 960 except StopIteration:
958 log.warning(_("This OMEMO encrypted stanza has not been encrypted " 961 log.warning(_("This OMEMO encrypted stanza has not been encrypted "
959 "for our device (device_id: {device_id}, fingerprint: " 962 "for our device (device_id: {device_id}, fingerprint: "
960 "{fingerprint}): {xml}").format( 963 "{fingerprint}): {xml}").format(
961 device_id=device_id, 964 device_id=device_id,
962 fingerprint=omemo_session.public_bundle.ik.encode('hex'), 965 fingerprint=omemo_session.public_bundle.ik.hex().upper(),
963 xml=encrypted_elt.toXml())) 966 xml=encrypted_elt.toXml()))
964 user_msg = (D_("An OMEMO message from {sender} has not been encrypted for " 967 user_msg = (D_("An OMEMO message from {sender} has not been encrypted for "
965 "our device, we can't decrypt it").format( 968 "our device, we can't decrypt it").format(
966 sender=from_jid.full())) 969 sender=from_jid.full()))
967 extra = {C.MESS_EXTRA_INFO: C.EXTRA_INFO_DECR_ERR} 970 extra = {C.MESS_EXTRA_INFO: C.EXTRA_INFO_DECR_ERR}
993 post_treat.addCallback(client.encryption.markAsUntrusted) 996 post_treat.addCallback(client.encryption.markAsUntrusted)
994 kwargs['allow_untrusted'] = True 997 kwargs['allow_untrusted'] = True
995 plaintext = yield omemo_session.decryptMessage(**kwargs) 998 plaintext = yield omemo_session.decryptMessage(**kwargs)
996 else: 999 else:
997 post_treat.addCallback(client.encryption.markAsTrusted) 1000 post_treat.addCallback(client.encryption.markAsTrusted)
1001 plaintext = plaintext.decode()
998 except Exception as e: 1002 except Exception as e:
999 log.warning(_("Can't decrypt message: {reason}\n{xml}").format( 1003 log.warning(_("Can't decrypt message: {reason}\n{xml}").format(
1000 reason=e, xml=message_elt.toXml())) 1004 reason=e, xml=message_elt.toXml()))
1001 user_msg = (D_("An OMEMO message from {sender} can't be decrypted: {reason}") 1005 user_msg = (D_("An OMEMO message from {sender} can't be decrypted: {reason}")
1002 .format(sender=from_jid.full(), reason=e)) 1006 .format(sender=from_jid.full(), reason=e))