diff --git a/omemo/modules/omemo.py b/omemo/modules/omemo.py index 3f62682..a2bc285 100644 --- a/omemo/modules/omemo.py +++ b/omemo/modules/omemo.py @@ -90,8 +90,6 @@ class OMEMO: self.query_for_bundles = [] self.query_for_devicelists = [] - app.ged.register_event_handler('pep-received', ged.PRECORE, - self.handle_device_list_update) app.ged.register_event_handler('signed-in', ged.PRECORE, self.signed_in) app.ged.register_event_handler('muc-config-changed', ged.GUI2, @@ -620,29 +618,40 @@ class OMEMO: stanza.addChild(node=node) obj.msg_iq = stanza - def handle_device_list_update(self, event): - """ Check if the passed event is a device list update and store the new - device ids. - - Parameters - ---------- - event : PEPReceivedEvent - - Returns - ------- - bool - True if the given event was a valid device list update event - """ - if event.conn.name != self._account: + def device_list_received(self, device_list, jid): + if not device_list: + log.error('%s => Received empty or invalid Devicelist from: %s', + self._account, jid) return - if event.pep_type != 'omemo-devicelist': - return + if self.get_own_jid().bareMatch(jid): + log.info('%s => Received own device list: %s', + self._account, device_list) + self.omemo.set_own_devices(device_list) + self.omemo.store.sessionStore.setActiveState( + device_list, self.own_jid) - self._handle_device_list_update(None, event.stanza) + # remove contact from list, so on send button pressed + # we query for bundle and build a session + if jid in self.query_for_bundles: + self.query_for_bundles.remove(jid) + + if not self.omemo.own_device_id_published(): + # Our own device_id is not in the list, it could be + # overwritten by some other client + self.publish_own_devices_list() + else: + log.info('%s => Received device list for %s: %s', + self._account, jid, device_list) + self.omemo.set_devices(jid, device_list) + self.omemo.store.sessionStore.setActiveState( + device_list, jid) + + # remove contact from list, so on send button pressed + # we query for bundle and build a session + if jid in self.query_for_bundles: + self.query_for_bundles.remove(jid) - # Don't propagate event further - return True def _handle_device_list_update(self, conn, stanza, fetch_bundle=False): """ Check if the passed event is a device list update and store the new diff --git a/omemo/modules/omemo_devicelist.py b/omemo/modules/omemo_devicelist.py new file mode 100644 index 0000000..c57eb37 --- /dev/null +++ b/omemo/modules/omemo_devicelist.py @@ -0,0 +1,77 @@ +# Copyright (C) 2018 Philipp Hörist +# +# This file is part of OMEMO. +# +# OMEMO is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; version 3 only. +# +# OMEMO is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OMEMO. If not, see . + +# XEP-0384: OMEMO Encryption + +import logging + +import nbxmpp + +from gajim.common import app +from gajim.common.modules.pep import AbstractPEPModule, AbstractPEPData + +from omemo.modules.util import NS_OMEMO +from omemo.modules.util import NS_DEVICE_LIST +from omemo.modules.util import unpack_devicelist + +log = logging.getLogger('gajim.plugin_system.omemo.pep') + +# Module name +name = 'OMEMODevicelist' +zeroconf = False + + +class OMEMODevicelistData(AbstractPEPData): + + type_ = 'omemo-devicelist' + + +class OMEMODevicelist(AbstractPEPModule): + ''' + + + + + + + ''' + + name = 'omemo-devicelist' + namespace = NS_DEVICE_LIST + pep_class = OMEMODevicelistData + store_publish = True + _log = log + + @staticmethod + def _extract_info(item): + return unpack_devicelist(item) + + def _notification_received(self, jid, devicelist): + con = app.connections[self._account] + con.get_module('OMEMO').device_list_received(devicelist.data, + jid.getStripped()) + @staticmethod + def _build_node(devicelist): + list_node = nbxmpp.Node('list', {'xmlns': NS_OMEMO}) + if devicelist is None: + return list_node + for device in devicelist: + list_node.addChild('device', attrs={'id': device}) + return list_node + + +def get_instance(*args, **kwargs): + return OMEMODevicelist(*args, **kwargs), 'OMEMODevicelist' diff --git a/omemo/modules/util.py b/omemo/modules/util.py new file mode 100644 index 0000000..084aeb0 --- /dev/null +++ b/omemo/modules/util.py @@ -0,0 +1,46 @@ +# Copyright (C) 2018 Philipp Hörist +# +# This file is part of OMEMO. +# +# OMEMO is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; version 3 only. +# +# OMEMO is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OMEMO. If not, see . + +# XEP-0384: OMEMO Encryption + +import logging + +import nbxmpp + +from gajim.common.exceptions import StanzaMalformed + + +log = logging.getLogger('gajim.plugin_system.omemo') + +NS_OMEMO = 'eu.siacs.conversations.axolotl' +NS_DEVICE_LIST = NS_OMEMO + '.devicelist' + + +def unpack_devicelist(item): + list_ = item.getTag('list', namespace=NS_OMEMO) + if list_ is None: + raise StanzaMalformed('No list node') + + device_list = list_.getTags('device') + + devices = [] + for device in device_list: + id_ = device.getAttr('id') + if id_ is None: + raise StanzaMalformed('No id for device found') + + devices.append(int(id_)) + return devices diff --git a/omemo/omemoplugin.py b/omemo/omemoplugin.py index fde7f5b..b84f446 100644 --- a/omemo/omemoplugin.py +++ b/omemo/omemoplugin.py @@ -32,12 +32,10 @@ from gi.repository import Gdk from gajim import dialogs from gajim.common import app, ged -from gajim.common.pep import SUPPORTED_PERSONAL_USER_EVENTS from gajim.plugins import GajimPlugin from gajim.plugins.plugins_i18n import _ from gajim.groupchat_control import GroupchatControl -from omemo.xmpp import DevicelistPEP from omemo.gtk.key import KeyDialog from omemo.gtk.config import OMEMOConfigDialog @@ -72,6 +70,7 @@ except Exception as error: if not ERROR_MSG: try: from omemo.modules import omemo + from omemo.modules import omemo_devicelist except Exception as error: log.error(error) ERROR_MSG = 'Error: %s' % error @@ -102,7 +101,7 @@ class OmemoPlugin(GajimPlugin): } self.modules = [ omemo, - # omemo_devicelist, + omemo_devicelist, ] self.config_dialog = OMEMOConfigDialog(self) self.gui_extension_points = { @@ -119,7 +118,6 @@ class OmemoPlugin(GajimPlugin): self.encryption_state, None), 'update_caps': (self._update_caps, None)} - SUPPORTED_PERSONAL_USER_EVENTS.append(DevicelistPEP) self.disabled_accounts = [] self.windowinstances = {} diff --git a/omemo/xmpp.py b/omemo/xmpp.py index c2cab20..28ae76d 100644 --- a/omemo/xmpp.py +++ b/omemo/xmpp.py @@ -29,7 +29,6 @@ from nbxmpp.protocol import NS_PUBSUB, Iq from nbxmpp.simplexml import Node from gajim.common import app # pylint: disable=import-error -from gajim.common.pep import AbstractPEP # pylint: disable=import-error from gajim.plugins.helpers import log_calls # pylint: disable=import-error NS_PUBSUB_EVENT = NS_PUBSUB + '#event' @@ -91,14 +90,6 @@ class DevicelistQuery(Iq): self.addChild(node=pubsub) -class DevicelistPEP(AbstractPEP): - type_ = 'omemo-devicelist' - namespace = NS_DEVICE_LIST - - def _extract_info(self, items): - return ({}, []) - - def make_bundle(state_bundle): result = Node('bundle', attrs={'xmlns': NS_OMEMO}) prekey_pub_node = result.addChild(