diff sat/plugins/plugin_xep_0384.py @ 3028:ab2696e34d29

Python 3 port: /!\ this is a huge commit /!\ starting from this commit, SàT is needs Python 3.6+ /!\ SàT maybe be instable or some feature may not work anymore, this will improve with time This patch port backend, bridge and frontends to Python 3. Roughly this has been done this way: - 2to3 tools has been applied (with python 3.7) - all references to python2 have been replaced with python3 (notably shebangs) - fixed files not handled by 2to3 (notably the shell script) - several manual fixes - fixed issues reported by Python 3 that where not handled in Python 2 - replaced "async" with "async_" when needed (it's a reserved word from Python 3.7) - replaced zope's "implements" with @implementer decorator - temporary hack to handle data pickled in database, as str or bytes may be returned, to be checked later - fixed hash comparison for password - removed some code which is not needed anymore with Python 3 - deactivated some code which needs to be checked (notably certificate validation) - tested with jp, fixed reported issues until some basic commands worked - ported Primitivus (after porting dependencies like urwid satext) - more manual fixes
author Goffi <goffi@goffi.org>
date Tue, 13 Aug 2019 19:08:41 +0200
parents 03a09e16bf28
children ffcdd93b61fa
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0384.py	Wed Jul 31 11:31:22 2019 +0200
+++ b/sat/plugins/plugin_xep_0384.py	Tue Aug 13 19:08:41 2019 +0200
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 
 # SAT plugin for OMEMO encryption
@@ -39,21 +39,21 @@
     # from omemo import wireformat
 except ImportError as e:
     raise exceptions.MissingModule(
-        u'Missing module omemo, please download/install it. You can use '
-        u'"pip install omemo"'
+        'Missing module omemo, please download/install it. You can use '
+        '"pip install omemo"'
     )
 
 log = getLogger(__name__)
 
 PLUGIN_INFO = {
-    C.PI_NAME: u"OMEMO",
-    C.PI_IMPORT_NAME: u"XEP-0384",
-    C.PI_TYPE: u"SEC",
-    C.PI_PROTOCOLS: [u"XEP-0384"],
-    C.PI_DEPENDENCIES: [u"XEP-0163", u"XEP-0280", u"XEP-0334", u"XEP-0060"],
-    C.PI_MAIN: u"OMEMO",
-    C.PI_HANDLER: u"no",
-    C.PI_DESCRIPTION: _(u"""Implementation of OMEMO"""),
+    C.PI_NAME: "OMEMO",
+    C.PI_IMPORT_NAME: "XEP-0384",
+    C.PI_TYPE: "SEC",
+    C.PI_PROTOCOLS: ["XEP-0384"],
+    C.PI_DEPENDENCIES: ["XEP-0163", "XEP-0280", "XEP-0334", "XEP-0060"],
+    C.PI_MAIN: "OMEMO",
+    C.PI_HANDLER: "no",
+    C.PI_DESCRIPTION: _("""Implementation of OMEMO"""),
 }
 
 OMEMO_MIN_VER = (0, 10, 4)
@@ -159,53 +159,53 @@
         self.setCb(d, callback)
 
     def loadSession(self, callback, bare_jid, device_id):
-        key = u'\n'.join([KEY_SESSION, bare_jid, unicode(device_id)])
+        key = '\n'.join([KEY_SESSION, bare_jid, str(device_id)])
         d = self.data.get(key)
         self.setCb(d, callback)
 
     def storeSession(self, callback, bare_jid, device_id, session):
-        key = u'\n'.join([KEY_SESSION, bare_jid, unicode(device_id)])
+        key = '\n'.join([KEY_SESSION, bare_jid, str(device_id)])
         d = self.data.force(key, session)
         self.setCb(d, callback)
 
     def deleteSession(self, callback, bare_jid, device_id):
-        key = u'\n'.join([KEY_SESSION, bare_jid, unicode(device_id)])
+        key = '\n'.join([KEY_SESSION, bare_jid, str(device_id)])
         d = self.data.remove(key)
         self.setCb(d, callback)
 
     def loadActiveDevices(self, callback, bare_jid):
-        key = u'\n'.join([KEY_ACTIVE_DEVICES, bare_jid])
+        key = '\n'.join([KEY_ACTIVE_DEVICES, bare_jid])
         d = self.data.get(key, {})
         if callback is not None:
             self.setCb(d, callback)
         return d
 
     def loadInactiveDevices(self, callback, bare_jid):
-        key = u'\n'.join([KEY_INACTIVE_DEVICES, bare_jid])
+        key = '\n'.join([KEY_INACTIVE_DEVICES, bare_jid])
         d = self.data.get(key, {})
         if callback is not None:
             self.setCb(d, callback)
         return d
 
     def storeActiveDevices(self, callback, bare_jid, devices):
-        key = u'\n'.join([KEY_ACTIVE_DEVICES, bare_jid])
+        key = '\n'.join([KEY_ACTIVE_DEVICES, bare_jid])
         d = self._checkJid(bare_jid)
         d.addCallback(lambda _: self.data.force(key, devices))
         self.setCb(d, callback)
 
     def storeInactiveDevices(self, callback, bare_jid, devices):
-        key = u'\n'.join([KEY_INACTIVE_DEVICES, bare_jid])
+        key = '\n'.join([KEY_INACTIVE_DEVICES, bare_jid])
         d = self._checkJid(bare_jid)
         d.addCallback(lambda _: self.data.force(key, devices))
         self.setCb(d, callback)
 
     def storeTrust(self, callback, bare_jid, device_id, trust):
-        key = u'\n'.join([KEY_TRUST, bare_jid, unicode(device_id)])
+        key = '\n'.join([KEY_TRUST, bare_jid, str(device_id)])
         d = self.data.force(key, trust)
         self.setCb(d, callback)
 
     def loadTrust(self, callback, bare_jid, device_id):
-        key = u'\n'.join([KEY_TRUST, bare_jid, unicode(device_id)])
+        key = '\n'.join([KEY_TRUST, bare_jid, str(device_id)])
         d = self.data.get(key)
         if callback is not None:
             self.setCb(d, callback)
@@ -221,11 +221,11 @@
         failed = [success for success, __ in results if not success]
         if failed:
             log.warning(
-                u"delete JID failed for {failed_count} on {total_count} operations"
+                "delete JID failed for {failed_count} on {total_count} operations"
                 .format(failed_count=len(failed), total_count=len(results)))
         else:
             log.info(
-                u"Delete JID operation succeed ({total_count} operations)."
+                "Delete JID operation succeed ({total_count} operations)."
                 .format(total_count=len(results)))
 
     def _deleteJID_gotDevices(self, results, bare_jid):
@@ -240,7 +240,7 @@
             else:
                 for device_id in devices:
                     for key in (KEY_SESSION, KEY_TRUST):
-                        k = u'\n'.join([key, bare_jid, unicode(device_id)])
+                        k = '\n'.join([key, bare_jid, str(device_id)])
                         d_list.append(self.data.remove(k))
 
         d_list.append(self.data.remove(KEY_ACTIVE_DEVICES, bare_jid))
@@ -257,10 +257,10 @@
         """Retrieve all (in)actives of bare_jid, and delete all related keys"""
         d_list = []
 
-        key = u'\n'.join([KEY_ACTIVE_DEVICES, bare_jid])
+        key = '\n'.join([KEY_ACTIVE_DEVICES, bare_jid])
         d_list.append(self.data.get(key, []))
 
-        key = u'\n'.join([KEY_INACTIVE_DEVICES, bare_jid])
+        key = '\n'.join([KEY_INACTIVE_DEVICES, bare_jid])
         d_inactive = self.data.get(key, {})
         # inactive devices are returned as a dict mapping from devices_id to timestamp
         # but we only need devices ids
@@ -332,7 +332,7 @@
         else:
             bare_jids = [e.userhost() for e in bare_jids]
         if bundles is not None:
-            bundles = {e.userhost(): v for e, v in bundles.iteritems()}
+            bundles = {e.userhost(): v for e, v in bundles.items()}
         encrypt_mess_p = self._session.encryptMessage(
             bare_jids=bare_jids,
             plaintext=message.encode('utf-8'),
@@ -380,21 +380,21 @@
 class OMEMO(object):
 
     def __init__(self, host):
-        log.info(_(u"OMEMO plugin initialization (omemo module v{version})").format(
+        log.info(_("OMEMO plugin initialization (omemo module v{version})").format(
             version=omemo.__version__))
-        version = tuple(map(int, omemo.__version__.split(u'.')[:3]))
+        version = tuple(map(int, omemo.__version__.split('.')[:3]))
         if version < OMEMO_MIN_VER:
             log.warning(_(
-                u"Your version of omemo module is too old: {v[0]}.{v[1]}.{v[2]} is "
-                u"minimum required), please update.").format(v=OMEMO_MIN_VER))
+                "Your version of omemo module is too old: {v[0]}.{v[1]}.{v[2]} is "
+                "minimum required), please update.").format(v=OMEMO_MIN_VER))
             raise exceptions.CancelError("module is too old")
         self.host = host
-        self._p_hints = host.plugins[u"XEP-0334"]
-        self._p_carbons = host.plugins[u"XEP-0280"]
-        self._p = host.plugins[u"XEP-0060"]
+        self._p_hints = host.plugins["XEP-0334"]
+        self._p_carbons = host.plugins["XEP-0280"]
+        self._p = host.plugins["XEP-0060"]
         host.trigger.add("MessageReceived", self._messageReceivedTrigger, priority=100050)
         host.trigger.add("sendMessageData", self._sendMessageDataTrigger)
-        self.host.registerEncryptionPlugin(self, u"OMEMO", NS_OMEMO, 100)
+        self.host.registerEncryptionPlugin(self, "OMEMO", NS_OMEMO, 100)
         pep = host.plugins['XEP-0163']
         pep.addPEPEvent("OMEMO_DEVICES", NS_OMEMO_DEVICES, self.onNewDevices)
 
@@ -406,21 +406,21 @@
         client = self.host.getClient(profile)
         session = client._xep_0384_session
         answer = xml_tools.XMLUIResult2DataFormResult(xmlui_data)
-        for key, value in answer.iteritems():
-            if key.startswith(u'trust_'):
+        for key, value in answer.items():
+            if key.startswith('trust_'):
                 trust_id = key[6:]
             else:
                 continue
             data = trust_data[trust_id]
             trust = C.bool(value)
             if trust:
-                yield session.trust(data[u"jid"],
-                                    data[u"device"],
-                                    data[u"ik"])
+                yield session.trust(data["jid"],
+                                    data["device"],
+                                    data["ik"])
             else:
-                yield session.distrust(data[u"jid"],
-                                       data[u"device"],
-                                       data[u"ik"])
+                yield session.distrust(data["jid"],
+                                       data["device"],
+                                       data["ik"])
                 if expect_problems is not None:
                     expect_problems.setdefault(data.bare_jid, set()).add(data.device)
         defer.returnValue({})
@@ -449,7 +449,7 @@
         # we need entity_jid xor trust_data
         assert entity_jid and not trust_data or not entity_jid and trust_data
         if entity_jid and entity_jid.resource:
-            raise ValueError(u"A bare jid is expected")
+            raise ValueError("A bare jid is expected")
 
         session = client._xep_0384_session
 
@@ -458,7 +458,7 @@
             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():
+            for device_id, trust_info in trust_session_data['active'].items():
                 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
@@ -468,25 +468,25 @@
                                                                  [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,
+                                "Can't find bundle for device {device_id} of user "
+                                "{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
+                        "key": cache[device_id].ik,
+                        "trusted": False
                     }
 
                 ik = trust_info["key"]
-                trust_id = unicode(hash((bare_jid_s, device_id, ik)))
+                trust_id = str(hash((bare_jid_s, device_id, ik)))
                 trust_data[trust_id] = {
-                    u"jid": entity_jid,
-                    u"device": device_id,
-                    u"ik": ik,
-                    u"trusted": trust_info[u"trusted"],
+                    "jid": entity_jid,
+                    "device": device_id,
+                    "ik": ik,
+                    "trusted": trust_info["trusted"],
                     }
 
         if submit_id is None:
@@ -496,41 +496,41 @@
                                                    one_shot=True)
         xmlui = xml_tools.XMLUI(
             panel_type = C.XMLUI_FORM,
-            title = D_(u"OMEMO trust management"),
+            title = D_("OMEMO trust management"),
             submit_id = submit_id
         )
         xmlui.addText(D_(
-            u"This is OMEMO trusting system. You'll see below the devices of your "
-            u"contacts, and a checkbox to trust them or not. A trusted device "
-            u"can read your messages in plain text, so be sure to only validate "
-            u"devices that you are sure are belonging to your contact. It's better "
-            u"to do this when you are next to your contact and her/his device, so "
-            u"you can check the \"fingerprint\" (the number next to the device) "
-            u"yourself. Do *not* validate a device if the fingerprint is wrong!"))
+            "This is OMEMO trusting system. You'll see below the devices of your "
+            "contacts, and a checkbox to trust them or not. A trusted device "
+            "can read your messages in plain text, so be sure to only validate "
+            "devices that you are sure are belonging to your contact. It's better "
+            "to do this when you are next to your contact and her/his device, so "
+            "you can check the \"fingerprint\" (the number next to the device) "
+            "yourself. Do *not* validate a device if the fingerprint is wrong!"))
 
         xmlui.changeContainer("label")
-        xmlui.addLabel(D_(u"This device ID"))
-        xmlui.addText(unicode(client._xep_0384_device_id))
-        xmlui.addLabel(D_(u"This device fingerprint"))
+        xmlui.addLabel(D_("This device ID"))
+        xmlui.addText(str(client._xep_0384_device_id))
+        xmlui.addLabel(D_("This device fingerprint"))
         ik_hex = session.public_bundle.ik.encode('hex').upper()
-        fp_human = u' '.join([ik_hex[i:i+8] for i in range(0, len(ik_hex), 8)])
+        fp_human = ' '.join([ik_hex[i:i+8] for i in range(0, len(ik_hex), 8)])
         xmlui.addText(fp_human)
         xmlui.addEmpty()
         xmlui.addEmpty()
 
 
-        for trust_id, data in trust_data.iteritems():
-            xmlui.addLabel(D_(u"Contact"))
-            xmlui.addJid(data[u'jid'])
-            xmlui.addLabel(D_(u"Device ID"))
-            xmlui.addText(unicode(data[u'device']))
-            xmlui.addLabel(D_(u"Fingerprint"))
-            ik_hex = data[u'ik'].encode('hex').upper()
-            fp_human = u' '.join([ik_hex[i:i+8] for i in range(0, len(ik_hex), 8)])
+        for trust_id, data in trust_data.items():
+            xmlui.addLabel(D_("Contact"))
+            xmlui.addJid(data['jid'])
+            xmlui.addLabel(D_("Device ID"))
+            xmlui.addText(str(data['device']))
+            xmlui.addLabel(D_("Fingerprint"))
+            ik_hex = data['ik'].encode('hex').upper()
+            fp_human = ' '.join([ik_hex[i:i+8] for i in range(0, len(ik_hex), 8)])
             xmlui.addText(fp_human)
-            xmlui.addLabel(D_(u"Trust this device?"))
-            xmlui.addBool(u"trust_{}".format(trust_id),
-                          value=C.boolConst(data.get(u'trusted', False)))
+            xmlui.addLabel(D_("Trust this device?"))
+            xmlui.addBool("trust_{}".format(trust_id),
+                          value=C.boolConst(data.get('trusted', False)))
 
             xmlui.addEmpty()
             xmlui.addEmpty()
@@ -549,7 +549,7 @@
         # and our own device id
         device_id = yield persistent_dict.get(KEY_DEVICE_ID)
         if device_id is None:
-            log.info(_(u"We have no identity for this device yet, let's generate one"))
+            log.info(_("We have no identity for this device yet, let's generate one"))
             # we have a new device, we create device_id
             device_id = random.randint(1, 2**31-1)
             # we check that it's really unique
@@ -571,7 +571,7 @@
         client._xep_0384_device_id = device_id
         yield omemo_session.newDeviceList(client.jid, devices)
         if omemo_session.republish_bundle:
-            log.info(_(u"Saving public bundle for this device ({device_id})").format(
+            log.info(_("Saving public bundle for this device ({device_id})").format(
                 device_id=device_id))
             yield self.setBundle(client, omemo_session.public_bundle, device_id)
         client._xep_0384_ready.callback(None)
@@ -589,22 +589,22 @@
         """
         devices = set()
         if len(items) > 1:
-            log.warning(_(u"OMEMO devices list is stored in more that one items, "
-                          u"this is not expected"))
+            log.warning(_("OMEMO devices list is stored in more that one items, "
+                          "this is not expected"))
         if items:
             try:
                 list_elt = next(items[0].elements(NS_OMEMO, 'list'))
             except StopIteration:
-                log.warning(_(u"no list element found in OMEMO devices list"))
+                log.warning(_("no list element found in OMEMO devices list"))
                 return
             for device_elt in list_elt.elements(NS_OMEMO, 'device'):
                 try:
                     device_id = int(device_elt['id'])
                 except KeyError:
-                    log.warning(_(u'device element is missing "id" attribute: {elt}')
+                    log.warning(_('device element is missing "id" attribute: {elt}')
                                 .format(elt=device_elt.toXml()))
                 except ValueError:
-                    log.warning(_(u'invalid device id: {device_id}').format(
+                    log.warning(_('invalid device id: {device_id}').format(
                         device_id=device_elt['id']))
                 else:
                     devices.add(device_id)
@@ -624,7 +624,7 @@
             items, metadata = yield self._p.getItems(client, entity_jid, NS_OMEMO_DEVICES)
         except error.StanzaError as e:
             if e.condition == 'item-not-found':
-                log.info(_(u"there is no node to handle OMEMO devices"))
+                log.info(_("there is no node to handle OMEMO devices"))
                 defer.returnValue(set())
             raise e
 
@@ -632,13 +632,13 @@
         defer.returnValue(devices)
 
     def setDevicesEb(self, failure_):
-        log.warning(_(u"Can't set devices: {reason}").format(reason=failure_))
+        log.warning(_("Can't set devices: {reason}").format(reason=failure_))
 
     def setDevices(self, client, devices):
         list_elt = domish.Element((NS_OMEMO, 'list'))
         for device in devices:
             device_elt = list_elt.addElement('device')
-            device_elt['id'] = unicode(device)
+            device_elt['id'] = str(device)
         d = self._p.sendItem(
             client, None, NS_OMEMO_DEVICES, list_elt, item_id=self._p.ID_SINGLETON)
         d.addErrback(self.setDevicesEb)
@@ -666,23 +666,23 @@
             try:
                 items, metadata = yield self._p.getItems(client, entity_jid, node)
             except error.StanzaError as e:
-                if e.condition == u"item-not-found":
-                    log.warning(_(u"Bundle missing for device {device_id}")
+                if e.condition == "item-not-found":
+                    log.warning(_("Bundle missing for device {device_id}")
                         .format(device_id=device_id))
                     missing.add(device_id)
                     continue
                 else:
-                    log.warning(_(u"Can't get bundle for device {device_id}: {reason}")
+                    log.warning(_("Can't get bundle for device {device_id}: {reason}")
                         .format(device_id=device_id, reason=e))
                     continue
             if not items:
-                log.warning(_(u"no item found in node {node}, can't get public bundle "
-                              u"for device {device_id}").format(node=node,
+                log.warning(_("no item found in node {node}, can't get public bundle "
+                              "for device {device_id}").format(node=node,
                                                                 device_id=device_id))
                 continue
             if len(items) > 1:
-                log.warning(_(u"more than one item found in {node}, "
-                              u"this is not expected").format(node=node))
+                log.warning(_("more than one item found in {node}, "
+                              "this is not expected").format(node=node))
             item = items[0]
             try:
                 bundle_elt = next(item.elements(NS_OMEMO, 'bundle'))
@@ -695,23 +695,23 @@
                 prekeys_elt =  next(bundle_elt.elements(
                     NS_OMEMO, 'prekeys'))
             except StopIteration:
-                log.warning(_(u"invalid bundle for device {device_id}, ignoring").format(
+                log.warning(_("invalid bundle for device {device_id}, ignoring").format(
                     device_id=device_id))
                 continue
 
             try:
-                spkPublic = base64.b64decode(unicode(signedPreKeyPublic_elt))
+                spkPublic = base64.b64decode(str(signedPreKeyPublic_elt))
                 spkSignature = base64.b64decode(
-                    unicode(signedPreKeySignature_elt))
+                    str(signedPreKeySignature_elt))
 
-                ik = base64.b64decode(unicode(identityKey_elt))
+                ik = base64.b64decode(str(identityKey_elt))
                 spk = {
                     "key": spkPublic,
                     "id": int(signedPreKeyPublic_elt['signedPreKeyId'])
                 }
                 otpks = []
                 for preKeyPublic_elt in prekeys_elt.elements(NS_OMEMO, 'preKeyPublic'):
-                    preKeyPublic = base64.b64decode(unicode(preKeyPublic_elt))
+                    preKeyPublic = base64.b64decode(str(preKeyPublic_elt))
                     otpk = {
                         "key": preKeyPublic,
                         "id": int(preKeyPublic_elt['preKeyId'])
@@ -719,7 +719,7 @@
                     otpks.append(otpk)
 
             except Exception as e:
-                log.warning(_(u"error while decoding key for device {device_id}: {msg}")
+                log.warning(_("error while decoding key for device {device_id}: {msg}")
                             .format(device_id=device_id, msg=e))
                 continue
 
@@ -729,20 +729,20 @@
         defer.returnValue((bundles, missing))
 
     def setBundleEb(self, failure_):
-        log.warning(_(u"Can't set bundle: {reason}").format(reason=failure_))
+        log.warning(_("Can't set bundle: {reason}").format(reason=failure_))
 
     def setBundle(self, client, bundle, device_id):
         """Set public bundle for this device.
 
         @param bundle(ExtendedPublicBundle): bundle to publish
         """
-        log.debug(_(u"updating bundle for {device_id}").format(device_id=device_id))
+        log.debug(_("updating bundle for {device_id}").format(device_id=device_id))
         bundle = bundle.serialize(omemo_backend)
         bundle_elt = domish.Element((NS_OMEMO, 'bundle'))
         signedPreKeyPublic_elt = bundle_elt.addElement(
             "signedPreKeyPublic",
             content=b64enc(bundle["spk"]['key']))
-        signedPreKeyPublic_elt['signedPreKeyId'] = unicode(bundle["spk"]['id'])
+        signedPreKeyPublic_elt['signedPreKeyId'] = str(bundle["spk"]['id'])
 
         bundle_elt.addElement(
             "signedPreKeySignature",
@@ -757,7 +757,7 @@
             preKeyPublic_elt = prekeys_elt.addElement(
                 'preKeyPublic',
                 content=b64enc(otpk["key"]))
-            preKeyPublic_elt['preKeyId'] = unicode(otpk['id'])
+            preKeyPublic_elt['preKeyId'] = str(otpk['id'])
 
         node = NS_OMEMO_BUNDLE.format(device_id=device_id)
         d = self._p.sendItem(client, None, node, bundle_elt, item_id=self._p.ID_SINGLETON)
@@ -782,7 +782,7 @@
         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"))
+                log.warning(_("Our own device is missing from devices list, fixing it"))
                 devices.add(own_device)
                 yield self.setDevices(client, devices)
 
@@ -809,7 +809,7 @@
         cache = client._xep_0384_cache
         for problem in problems:
             if isinstance(problem, omemo_excpt.TrustException):
-                untrusted[unicode(hash(problem))] = problem
+                untrusted[str(hash(problem))] = problem
             elif isinstance(problem, omemo_excpt.MissingBundleException):
                 pb_entity = jid.JID(problem.bare_jid)
                 entity_cache = cache.setdefault(pb_entity, {})
@@ -835,39 +835,39 @@
             else:
                 raise problem
 
-        for peer_jid, devices in missing_bundles.iteritems():
-            devices_s = [unicode(d) for d in devices]
+        for peer_jid, devices in missing_bundles.items():
+            devices_s = [str(d) for d in devices]
             log.warning(
-                _(u"Can't retrieve bundle for device(s) {devices} of entity {peer}, "
-                  u"the message will not be readable on this/those device(s)").format(
-                    devices=u", ".join(devices_s), peer=peer_jid.full()))
+                _("Can't retrieve bundle for device(s) {devices} of entity {peer}, "
+                  "the message will not be readable on this/those device(s)").format(
+                    devices=", ".join(devices_s), peer=peer_jid.full()))
             client.feedback(
                 entity,
-                D_(u"You're destinee {peer} has missing encryption data on some of "
-                   u"his/her device(s) (bundle on device {devices}), the message won't  "
-                   u"be readable on this/those device.").format(
-                   peer=peer_jid.full(), devices=u", ".join(devices_s)))
+                D_("You're destinee {peer} has missing encryption data on some of "
+                   "his/her device(s) (bundle on device {devices}), the message won't  "
+                   "be readable on this/those device.").format(
+                   peer=peer_jid.full(), devices=", ".join(devices_s)))
 
         if untrusted:
             trust_data = {}
-            for trust_id, data in untrusted.iteritems():
+            for trust_id, data in untrusted.items():
                 trust_data[trust_id] = {
                     'jid': jid.JID(data.bare_jid),
                     'device':  data.device,
                     'ik': data.ik}
 
-            user_msg =  D_(u"Not all destination devices are trusted, we can't encrypt "
-                           u"message in such a situation. Please indicate if you trust "
-                           u"those devices or not in the trust manager before we can "
+            user_msg =  D_("Not all destination devices are trusted, we can't encrypt "
+                           "message in such a situation. Please indicate if you trust "
+                           "those devices or not in the trust manager before we can "
                            "send this message")
             client.feedback(entity, user_msg)
-            xmlui = yield self.getTrustUI(client, trust_data=trust_data, submit_id=u"")
+            xmlui = yield self.getTrustUI(client, trust_data=trust_data, submit_id="")
 
             answer = yield xml_tools.deferXMLUI(
                 self.host,
                 xmlui,
                 action_extra={
-                    u"meta_encryption_trust": NS_OMEMO,
+                    "meta_encryption_trust": NS_OMEMO,
                 },
                 profile=client.profile)
             yield self.trustUICb(answer, trust_data, expect_problems, client.profile)
@@ -881,7 +881,7 @@
         try:
             while True:
                 if loop_idx > 10:
-                    msg = _(u"Too many iterations in encryption loop")
+                    msg = _("Too many iterations in encryption loop")
                     log.error(msg)
                     raise exceptions.InternalError(msg)
                 # encryptMessage may fail, in case of e.g. trust issue or missing bundle
@@ -903,7 +903,7 @@
                 else:
                     break
         except Exception as e:
-            msg = _(u"Can't encrypt message for {entity}: {reason}".format(
+            msg = _("Can't encrypt message for {entity}: {reason}".format(
                 entity=entity_bare_jid.full(), reason=str(e).decode('utf-8', 'replace')))
             log.warning(msg)
             extra = {C.MESS_EXTRA_INFO: C.EXTRA_INFO_ENCR_ERR}
@@ -917,7 +917,7 @@
         if message_elt.getAttribute("type") == C.MESS_TYPE_GROUPCHAT:
             defer.returnValue(True)
         try:
-            encrypted_elt = next(message_elt.elements(NS_OMEMO, u"encrypted"))
+            encrypted_elt = next(message_elt.elements(NS_OMEMO, "encrypted"))
         except StopIteration:
             # no OMEMO message here
             defer.returnValue(True)
@@ -938,40 +938,40 @@
 
         device_id = client._xep_0384_device_id
         try:
-            header_elt = next(encrypted_elt.elements(NS_OMEMO, u'header'))
-            iv_elt = next(header_elt.elements(NS_OMEMO, u'iv'))
+            header_elt = next(encrypted_elt.elements(NS_OMEMO, 'header'))
+            iv_elt = next(header_elt.elements(NS_OMEMO, 'iv'))
         except StopIteration:
-            log.warning(_(u"Invalid OMEMO encrypted stanza, ignoring: {xml}")
+            log.warning(_("Invalid OMEMO encrypted stanza, ignoring: {xml}")
                 .format(xml=message_elt.toXml()))
             defer.returnValue(False)
         try:
             s_device_id = header_elt['sid']
         except KeyError:
-            log.warning(_(u"Invalid OMEMO encrypted stanza, missing sender device ID, "
-                          u"ignoring: {xml}")
+            log.warning(_("Invalid OMEMO encrypted stanza, missing sender device ID, "
+                          "ignoring: {xml}")
                 .format(xml=message_elt.toXml()))
             defer.returnValue(False)
         try:
-            key_elt = next((e for e in header_elt.elements(NS_OMEMO, u'key')
-                            if int(e[u'rid']) == device_id))
+            key_elt = next((e for e in header_elt.elements(NS_OMEMO, 'key')
+                            if int(e['rid']) == device_id))
         except StopIteration:
-            log.warning(_(u"This OMEMO encrypted stanza has not been encrypted "
-                          u"for our device (device_id: {device_id}, fingerprint: "
-                          u"{fingerprint}): {xml}").format(
+            log.warning(_("This OMEMO encrypted stanza has not been encrypted "
+                          "for our device (device_id: {device_id}, fingerprint: "
+                          "{fingerprint}): {xml}").format(
                           device_id=device_id,
                           fingerprint=omemo_session.public_bundle.ik.encode('hex'),
                           xml=encrypted_elt.toXml()))
-            user_msg = (D_(u"An OMEMO message from {sender} has not been encrypted for "
-                           u"our device, we can't decrypt it").format(
+            user_msg = (D_("An OMEMO message from {sender} has not been encrypted for "
+                           "our device, we can't decrypt it").format(
                            sender=from_jid.full()))
             extra = {C.MESS_EXTRA_INFO: C.EXTRA_INFO_DECR_ERR}
             client.feedback(feedback_jid, user_msg, extra)
             defer.returnValue(False)
         except ValueError as e:
-            log.warning(_(u"Invalid recipient ID: {msg}".format(msg=e)))
+            log.warning(_("Invalid recipient ID: {msg}".format(msg=e)))
             defer.returnValue(False)
         is_pre_key = C.bool(key_elt.getAttribute('prekey', 'false'))
-        payload_elt = next(encrypted_elt.elements(NS_OMEMO, u'payload'), None)
+        payload_elt = next(encrypted_elt.elements(NS_OMEMO, 'payload'), None)
         additional_information = {
             "from_storage": bool(message_elt.delay)
         }
@@ -996,9 +996,9 @@
             else:
                 post_treat.addCallback(client.encryption.markAsTrusted)
         except Exception as e:
-            log.warning(_(u"Can't decrypt message: {reason}\n{xml}").format(
+            log.warning(_("Can't decrypt message: {reason}\n{xml}").format(
                 reason=e, xml=message_elt.toXml()))
-            user_msg = (D_(u"An OMEMO message from {sender} can't be decrypted: {reason}")
+            user_msg = (D_("An OMEMO message from {sender} can't be decrypted: {reason}")
                 .format(sender=from_jid.full(), reason=e))
             extra = {C.MESS_EXTRA_INFO: C.EXTRA_INFO_DECR_ERR}
             client.feedback(feedback_jid, user_msg, extra)
@@ -1012,7 +1012,7 @@
 
         message_elt.children.remove(encrypted_elt)
         if plaintext:
-            message_elt.addElement("body", content=plaintext.decode('utf-8'))
+            message_elt.addElement("body", content=plaintext)
         post_treat.addCallback(client.encryption.markAsEncrypted)
         defer.returnValue(True)
 
@@ -1023,7 +1023,7 @@
             return
         message_elt = mess_data["xml"]
         to_jid = mess_data["to"].userhostJID()
-        log.debug(u"encrypting message")
+        log.debug("encrypting message")
         body = None
         for child in list(message_elt.children):
             if child.name == "body":
@@ -1037,21 +1037,21 @@
                 message_elt.children.remove(child)
 
         if body is None:
-            log.warning(u"No message found")
+            log.warning("No message found")
             return
 
-        encryption_data = yield self.encryptMessage(client, to_jid, unicode(body))
+        encryption_data = yield self.encryptMessage(client, to_jid, str(body))
 
         encrypted_elt = message_elt.addElement((NS_OMEMO, 'encrypted'))
         header_elt = encrypted_elt.addElement('header')
-        header_elt['sid'] = unicode(encryption_data['sid'])
+        header_elt['sid'] = str(encryption_data['sid'])
         bare_jid_s = to_jid.userhost()
 
-        for rid, data in encryption_data['keys'][bare_jid_s].iteritems():
+        for rid, data in encryption_data['keys'][bare_jid_s].items():
             key_elt = header_elt.addElement(
                 'key',
                 content=b64enc(data['data']))
-            key_elt['rid'] = unicode(rid)
+            key_elt['rid'] = str(rid)
             if data['pre_key']:
                 key_elt['prekey'] = 'true'