[omemo] Adapt to Gajim changes

This commit is contained in:
Philipp Hörist
2018-12-31 01:51:17 +01:00
parent 5fc7a77526
commit 6634da0a79
5 changed files with 157 additions and 113 deletions

View File

@@ -171,7 +171,7 @@ class OMEMOConfigDialog(GajimPluginConfigDialog):
def cleardevice_button_clicked_cb(self, button, *args): def cleardevice_button_clicked_cb(self, button, *args):
active = self._ui.get_object('account_combobox').get_active() active = self._ui.get_object('account_combobox').get_active()
account = self.account_store[active][0] account = self.account_store[active][0]
self.plugin.connections[account].publish_own_devices_list(new=True) app.connections[account].get_module('OMEMO').publish_own_devices_list(new=True)
self.update_context_list() self.update_context_list()
def refresh_button_clicked_cb(self, button, *args): def refresh_button_clicked_cb(self, button, *args):

View File

@@ -60,7 +60,7 @@ class KeyDialog(Gtk.Dialog):
self._windowinstances = windowinstances self._windowinstances = windowinstances
self._account = self._contact.account.name self._account = self._contact.account.name
self._plugin = plugin self._plugin = plugin
self._con = plugin.connections[self._account] self._con = app.connections[self._account].get_module('OMEMO')
self.omemostate = self._plugin.get_omemo(self._account) self.omemostate = self._plugin.get_omemo(self._account)
self._own_jid = app.get_jid_from_account(self._account) self._own_jid = app.get_jid_from_account(self._account)

View File

View File

@@ -1,3 +1,21 @@
# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
#
# 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 <http://www.gnu.org/licenses/>.
# XEP-0384: OMEMO Encryption
import os import os
import time import time
import logging import logging
@@ -5,12 +23,16 @@ import sqlite3
import nbxmpp import nbxmpp
from nbxmpp.simplexml import Node from nbxmpp.simplexml import Node
from nbxmpp import JID from nbxmpp.protocol import JID
from nbxmpp.const import StatusCode
from nbxmpp.const import PresenceType
from nbxmpp.structs import StanzaHandler
from gajim.common import app from gajim.common import app
from gajim.common import ged from gajim.common import ged
from gajim.common import helpers from gajim.common import helpers
from gajim.common import configpaths from gajim.common import configpaths
from gajim.common.nec import NetworkEvent
from gajim.common.connection_handlers_events import MessageNotSentEvent from gajim.common.connection_handlers_events import MessageNotSentEvent
from gajim.plugins.plugins_i18n import _ from gajim.plugins.plugins_i18n import _
@@ -39,12 +61,27 @@ ALLOWED_TAGS = [('request', nbxmpp.NS_RECEIPTS),
log = logging.getLogger('gajim.plugin_system.omemo') log = logging.getLogger('gajim.plugin_system.omemo')
ENCRYPTION_NAME = 'OMEMO'
class OMEMOConnection: # Module name
def __init__(self, account, plugin): name = 'OMEMO'
self.account = account zeroconf = False
self.plugin = plugin
self.own_jid = self.get_own_jid(stripped=True)
class OMEMO:
def __init__(self, con):
self._con = con
self._account = con.name
self.handlers = [
StanzaHandler(name='presence',
callback=self._on_muc_user_presence,
ns=nbxmpp.NS_MUC_USER,
priority=48),
]
self.available = True
# self.plugin = plugin
self.own_jid = self._con.get_own_jid().getStripped()
self.omemo = self.__get_omemo() self.omemo = self.__get_omemo()
self.groupchat = {} self.groupchat = {}
@@ -57,25 +94,20 @@ class OMEMOConnection:
self.handle_device_list_update) self.handle_device_list_update)
app.ged.register_event_handler('signed-in', ged.PRECORE, app.ged.register_event_handler('signed-in', ged.PRECORE,
self.signed_in) self.signed_in)
app.ged.register_event_handler('gc-presence-received', ged.PRECORE, app.ged.register_event_handler('muc-config-changed', ged.GUI2,
self.gc_presence_received) self._on_config_changed)
app.ged.register_event_handler('gc-config-changed-received', ged.PRECORE,
self.gc_config_changed_received)
def get_con(self):
return app.connections[self.account]
def send_with_callback(self, stanza, callback, data=None): def send_with_callback(self, stanza, callback, data=None):
if data is None: if data is None:
self.get_con().connection.SendAndCallForResponse(stanza, callback) self._con.connection.SendAndCallForResponse(stanza, callback)
else: else:
self.get_con().connection.SendAndCallForResponse( self._con.connection.SendAndCallForResponse(
stanza, callback, data) stanza, callback, data)
def get_own_jid(self, stripped=False): def get_own_jid(self, stripped=False):
if stripped: if stripped:
return self.get_con().get_own_jid().getStripped() return self._con.get_own_jid().getStripped()
return self.get_con().get_own_jid() return self._con.get_own_jid()
def __get_omemo(self): def __get_omemo(self):
""" Returns the the OmemoState for the specified account. """ Returns the the OmemoState for the specified account.
@@ -94,7 +126,7 @@ class OMEMOConnection:
db_path = os.path.join(data_dir, 'omemo_' + self.own_jid + '.db') db_path = os.path.join(data_dir, 'omemo_' + self.own_jid + '.db')
conn = sqlite3.connect(db_path, check_same_thread=False) conn = sqlite3.connect(db_path, check_same_thread=False)
conn.execute("PRAGMA secure_delete=1") conn.execute("PRAGMA secure_delete=1")
return OmemoState(self.own_jid, conn, self.account, self) return OmemoState(self.own_jid, conn, self._account, self)
def signed_in(self, event): def signed_in(self, event):
""" Method called on SignIn """ Method called on SignIn
@@ -103,9 +135,10 @@ class OMEMOConnection:
---------- ----------
event : SignedInEvent event : SignedInEvent
""" """
if event.conn.name != self.account: if event.conn.name != self._account:
return return
log.info('%s => Announce Support after Sign In', self.account)
log.info('%s => Announce Support after Sign In', self._account)
self.query_for_bundles = [] self.query_for_bundles = []
self.publish_bundle() self.publish_bundle()
self.query_devicelist() self.query_devicelist()
@@ -113,13 +146,13 @@ class OMEMOConnection:
def activate(self): def activate(self):
""" Method called when the Plugin is activated in the PluginManager """ Method called when the Plugin is activated in the PluginManager
""" """
if app.caps_hash[self.account] != '': if app.caps_hash[self._account] != '':
# Gajim has already a caps hash calculated, update it # Gajim has already a caps hash calculated, update it
helpers.update_optional_features(self.account) helpers.update_optional_features(self._account)
if app.account_is_connected(self.account): if app.account_is_connected(self._account):
log.info('%s => Announce Support after Plugin Activation', log.info('%s => Announce Support after Plugin Activation',
self.account) self._account)
self.query_for_bundles = [] self.query_for_bundles = []
self.publish_bundle() self.publish_bundle()
self.query_devicelist() self.query_devicelist()
@@ -160,7 +193,7 @@ class OMEMOConnection:
------- -------
Return means that the Event is passed on to Gajim Return means that the Event is passed on to Gajim
""" """
if event.conn.name != self.account: if event.conn.name != self._account:
return return
# Compatibility for Gajim 1.0.3 # Compatibility for Gajim 1.0.3
@@ -175,10 +208,10 @@ class OMEMOConnection:
if event.real_jid is None: if event.real_jid is None:
log.error('%s => Received Groupchat Message without real jid', log.error('%s => Received Groupchat Message without real jid',
self.account) self._account)
return return
log.info('%s => Groupchat Message received', self.account) log.info('%s => Groupchat Message received', self._account)
msg_dict = unpack_encrypted(omemo) msg_dict = unpack_encrypted(omemo)
msg_dict['sender_jid'] = JID(event.real_jid).getStripped() msg_dict['sender_jid'] = JID(event.real_jid).getStripped()
@@ -192,7 +225,7 @@ class OMEMOConnection:
self.print_msg_to_log(message) self.print_msg_to_log(message)
event.msgtxt = plaintext event.msgtxt = plaintext
event.encrypted = self.plugin.encryption_name event.encrypted = ENCRYPTION_NAME
self.add_additional_data(event.additional_data) self.add_additional_data(event.additional_data)
def _mam_message_received(self, event): def _mam_message_received(self, event):
@@ -209,7 +242,7 @@ class OMEMOConnection:
------- -------
Return means that the Event is passed on to Gajim Return means that the Event is passed on to Gajim
""" """
if event.conn.name != self.account: if event.conn.name != self._account:
return return
# Compatibility for Gajim 1.0.3 # Compatibility for Gajim 1.0.3
@@ -220,7 +253,7 @@ class OMEMOConnection:
omemo_encrypted_tag = message.getTag('encrypted', namespace=NS_OMEMO) omemo_encrypted_tag = message.getTag('encrypted', namespace=NS_OMEMO)
if omemo_encrypted_tag: if omemo_encrypted_tag:
log.debug('%s => OMEMO MAM msg received', self.account) log.debug('%s => OMEMO MAM msg received', self._account)
msg_dict = unpack_encrypted(omemo_encrypted_tag) msg_dict = unpack_encrypted(omemo_encrypted_tag)
if msg_dict is None: if msg_dict is None:
@@ -239,7 +272,7 @@ class OMEMOConnection:
self.print_msg_to_log(message) self.print_msg_to_log(message)
event.msgtxt = plaintext event.msgtxt = plaintext
event.encrypted = self.plugin.encryption_name event.encrypted = ENCRYPTION_NAME
self.add_additional_data(event.additional_data) self.add_additional_data(event.additional_data)
return return
@@ -257,10 +290,10 @@ class OMEMOConnection:
------- -------
Return means that the Event is passed on to Gajim Return means that the Event is passed on to Gajim
""" """
if msg.conn.name != self.account: if msg.conn.name != self._account:
return return
if msg.stanza.getTag('encrypted', namespace=NS_OMEMO): if msg.stanza.getTag('encrypted', namespace=NS_OMEMO):
log.debug('%s => OMEMO msg received', self.account) log.debug('%s => OMEMO msg received', self._account)
if msg.forwarded and msg.sent: if msg.forwarded and msg.sent:
from_jid = self.own_jid from_jid = self.own_jid
@@ -288,7 +321,7 @@ class OMEMOConnection:
getJidFromDevice(msg_dict['sid']) getJidFromDevice(msg_dict['sid'])
if not from_jid: if not from_jid:
log.error("%s => Can't decrypt GroupChat Message " log.error("%s => Can't decrypt GroupChat Message "
"from %s", self.account, msg.resource) "from %s", self._account, msg.resource)
msg.encrypted = 'drop' msg.encrypted = 'drop'
return return
self.groupchat[msg.jid][msg.resource] = from_jid self.groupchat[msg.jid][msg.resource] = from_jid
@@ -302,7 +335,7 @@ class OMEMOConnection:
del self.gc_message[msg_dict['payload']] del self.gc_message[msg_dict['payload']]
else: else:
log.error("%s => Can't decrypt own GroupChat Message", log.error("%s => Can't decrypt own GroupChat Message",
self.account) self._account)
msg.encrypted = 'drop' msg.encrypted = 'drop'
return return
else: else:
@@ -318,7 +351,7 @@ class OMEMOConnection:
# Gajim bug: there must be a body or the message # Gajim bug: there must be a body or the message
# gets dropped from history # gets dropped from history
msg.stanza.setBody(plaintext) msg.stanza.setBody(plaintext)
msg.encrypted = self.plugin.encryption_name msg.encrypted = ENCRYPTION_NAME
self.add_additional_data(msg.additional_data) self.add_additional_data(msg.additional_data)
def room_memberlist_received(self, stanza): def room_memberlist_received(self, stanza):
@@ -364,38 +397,43 @@ class OMEMOConnection:
def is_contact_in_roster(self, jid): def is_contact_in_roster(self, jid):
if jid == self.own_jid: if jid == self.own_jid:
return True return True
contact = app.contacts.get_first_contact_from_jid(self.account, jid) contact = app.contacts.get_first_contact_from_jid(self._account, jid)
if contact is None: if contact is None:
return False return False
return contact.sub == 'both' return contact.sub == 'both'
def gc_presence_received(self, event): def _on_muc_user_presence(self, _con, _stanza, properties):
if event.conn.name != self.account: if properties.type == PresenceType.ERROR:
return
if not hasattr(event, 'real_jid') or not event.real_jid:
return return
room = event.room_jid room = properties.jid.getBare()
jid = app.get_jid_without_resource(event.real_jid) nick = properties.muc_nickname
nick = event.nick status_codes = properties.muc_status_codes or []
muc_user = properties.muc_user
if muc_user is None:
return
jid = properties.muc_user.jid.getBare()
if properties.is_nickname_changed:
new_nick = properties.muc_user.nick
if '303' in event.status_code: # Nick Changed
if room in self.groupchat: if room in self.groupchat:
if nick in self.groupchat[room]: if nick in self.groupchat[room]:
del self.groupchat[room][nick] del self.groupchat[room][nick]
self.groupchat[room][event.new_nick] = jid self.groupchat[room][new_nick] = jid
log.debug('Nick Change: old: %s, new: %s, jid: %s ', log.debug('Nick Change: old: %s, new: %s, jid: %s ',
nick, event.new_nick, jid) nick, new_nick, jid)
log.debug('Members after Change: %s', self.groupchat[room]) log.debug('Members after Change: %s', self.groupchat[room])
else: else:
if nick in self.temp_groupchat[room]: if nick in self.temp_groupchat[room]:
del self.temp_groupchat[room][nick] del self.temp_groupchat[room][nick]
self.temp_groupchat[room][event.new_nick] = jid self.temp_groupchat[room][new_nick] = jid
return return
if room not in self.groupchat: if room not in self.groupchat:
if room not in self.temp_groupchat: if room not in self.temp_groupchat:
self.temp_groupchat[room] = {} self.temp_groupchat[room] = {}
@@ -417,34 +455,35 @@ class OMEMOConnection:
log.info('%s not in Roster, query devicelist...', jid) log.info('%s not in Roster, query devicelist...', jid)
self.query_devicelist(jid) self.query_devicelist(jid)
if '100' in event.status_code: # non-anonymous Room (Full JID) if properties.is_muc_self_presence:
if StatusCode.NON_ANONYMOUS in status_codes:
# non-anonymous Room (Full JID)
if room not in self.groupchat:
self.groupchat[room] = self.temp_groupchat[room]
if room not in self.groupchat: log.info('OMEMO capable Room found: %s', room)
self.groupchat[room] = self.temp_groupchat[room]
log.info('OMEMO capable Room found: %s', room) self.get_affiliation_list(room, 'owner')
self.get_affiliation_list(room, 'admin')
self.get_affiliation_list(room, 'owner') self.get_affiliation_list(room, 'member')
self.get_affiliation_list(room, 'admin')
self.get_affiliation_list(room, 'member')
def get_affiliation_list(self, room_jid, affiliation): def get_affiliation_list(self, room_jid, affiliation):
iq = nbxmpp.Iq(typ='get', to=room_jid, queryNS=nbxmpp.NS_MUC_ADMIN) iq = nbxmpp.Iq(typ='get', to=room_jid, queryNS=nbxmpp.NS_MUC_ADMIN)
item = iq.setQuery().setTag('item') item = iq.setQuery().setTag('item')
item.setAttr('affiliation', affiliation) item.setAttr('affiliation', affiliation)
self.get_con().connection.SendAndCallForResponse( self._con.connection.SendAndCallForResponse(
iq, self.room_memberlist_received) iq, self.room_memberlist_received)
def gc_config_changed_received(self, event): def _on_config_changed(self, event):
if event.conn.name != self.account: if event.account != self._account:
return return
room = event.room_jid
if '172' in event.status_code: room = event.jid.getBare()
status_codes = event.status_codes or []
if StatusCode.CONFIG_NON_ANONYMOUS in status_codes:
if room not in self.groupchat: if room not in self.groupchat:
self.groupchat[room] = self.temp_groupchat[room] self.groupchat[room] = self.temp_groupchat[room]
log.debug('CONFIG CHANGE') log.info('Room config change: non-anonymous')
log.debug(event.room_jid)
log.debug(event.status_code)
def gc_encrypt_message(self, conn, event, callback): def gc_encrypt_message(self, conn, event, callback):
""" Manipulates the outgoing groupchat stanza """ Manipulates the outgoing groupchat stanza
@@ -462,7 +501,7 @@ class OMEMOConnection:
This prevents any accidental sending of unencrypted messages. This prevents any accidental sending of unencrypted messages.
""" """
if event.conn.name != self.account: if event.conn.name != self._account:
return return
try: try:
self.cleanup_stanza(event) self.cleanup_stanza(event)
@@ -524,7 +563,7 @@ class OMEMOConnection:
The callback. Its only called if the stanza was encrypted. The callback. Its only called if the stanza was encrypted.
This prevents any accidental sending of unencrypted messages. This prevents any accidental sending of unencrypted messages.
""" """
if event.conn.name != self.account: if event.conn.name != self._account:
return return
try: try:
self.cleanup_stanza(event) self.cleanup_stanza(event)
@@ -562,7 +601,7 @@ class OMEMOConnection:
event.msg_iq.addChild(node=store) event.msg_iq.addChild(node=store)
self.print_msg_to_log(event.msg_iq) self.print_msg_to_log(event.msg_iq)
event.xhtml = None event.xhtml = None
event.encrypted = self.plugin.encryption_name event.encrypted = ENCRYPTION_NAME
self.add_additional_data(event.additional_data) self.add_additional_data(event.additional_data)
callback(event) callback(event)
@@ -594,7 +633,7 @@ class OMEMOConnection:
bool bool
True if the given event was a valid device list update event True if the given event was a valid device list update event
""" """
if event.conn.name != self.account: if event.conn.name != self._account:
return return
if event.pep_type != 'omemo-devicelist': if event.pep_type != 'omemo-devicelist':
@@ -620,16 +659,16 @@ class OMEMOConnection:
""" """
devices_list = list(set(unpack_device_list_update(stanza, devices_list = list(set(unpack_device_list_update(stanza,
self.account))) self._account)))
contact_jid = stanza.getFrom().getStripped() contact_jid = stanza.getFrom().getStripped()
if not devices_list: if not devices_list:
log.error('%s => Received empty or invalid Devicelist from: %s', log.error('%s => Received empty or invalid Devicelist from: %s',
self.account, contact_jid) self._account, contact_jid)
return False return False
if self.get_own_jid().bareMatch(contact_jid): if self.get_own_jid().bareMatch(contact_jid):
log.info('%s => Received own device list: %s', log.info('%s => Received own device list: %s',
self.account, devices_list) self._account, devices_list)
self.omemo.set_own_devices(devices_list) self.omemo.set_own_devices(devices_list)
self.omemo.store.sessionStore.setActiveState( self.omemo.store.sessionStore.setActiveState(
devices_list, self.own_jid) devices_list, self.own_jid)
@@ -645,7 +684,7 @@ class OMEMOConnection:
self.publish_own_devices_list() self.publish_own_devices_list()
else: else:
log.info('%s => Received device list for %s: %s', log.info('%s => Received device list for %s: %s',
self.account, contact_jid, devices_list) self._account, contact_jid, devices_list)
self.omemo.set_devices(contact_jid, devices_list) self.omemo.set_devices(contact_jid, devices_list)
self.omemo.store.sessionStore.setActiveState( self.omemo.store.sessionStore.setActiveState(
devices_list, contact_jid) devices_list, contact_jid)
@@ -681,18 +720,18 @@ class OMEMOConnection:
for device in devices_list: for device in devices_list:
list_node.addChild('device').setAttr('id', device) list_node.addChild('device').setAttr('id', device)
con = app.connections[self.account] con = app.connections[self._account]
con.get_module('PubSub').send_pb_publish( con.get_module('PubSub').send_pb_publish(
'', NS_DEVICE_LIST, list_node, 'current', '', NS_DEVICE_LIST, list_node, 'current',
cb=self.device_list_publish_result) cb=self.device_list_publish_result)
log.info('%s => Publishing own Devices: %s', log.info('%s => Publishing own Devices: %s',
self.account, devices_list) self._account, devices_list)
def device_list_publish_result(self, _con, stanza): def device_list_publish_result(self, _con, stanza):
if not nbxmpp.isResultNode(stanza): if not nbxmpp.isResultNode(stanza):
log.error('%s => Publishing devicelist failed: %s', log.error('%s => Publishing devicelist failed: %s',
self.account, stanza.getError()) self._account, stanza.getError())
def are_keys_missing(self, contact_jid): def are_keys_missing(self, contact_jid):
""" Checks if devicekeys are missing and queries the """ Checks if devicekeys are missing and queries the
@@ -751,7 +790,7 @@ class OMEMOConnection:
The device id for which we want the bundle The device id for which we want the bundle
""" """
log.info('%s => Fetch bundle device %s#%s', log.info('%s => Fetch bundle device %s#%s',
self.account, device_id, jid) self._account, device_id, jid)
bundle_query = BundleInformationQuery(jid, device_id) bundle_query = BundleInformationQuery(jid, device_id)
self.send_with_callback(bundle_query, self.send_with_callback(bundle_query,
self.session_from_prekey_bundle, self.session_from_prekey_bundle,
@@ -783,13 +822,14 @@ class OMEMOConnection:
if self.omemo.build_session(jid, device_id, bundle_dict): if self.omemo.build_session(jid, device_id, bundle_dict):
log.info('%s => session created for: %s', log.info('%s => session created for: %s',
self.account, jid) self._account, jid)
# Trigger dialog to trust new Fingerprints if # Trigger dialog to trust new Fingerprints if
# the Chat Window is Open # the Chat Window is Open
ctrl = app.interface.msg_win_mgr.get_control( ctrl = app.interface.msg_win_mgr.get_control(
jid, self.account) jid, self._account)
if ctrl: if ctrl:
self.plugin.new_fingerprints_available(ctrl) app.nec.push_incoming_event(
NetworkEvent('omemo-new-fingerprint', chat_control=ctrl))
def query_devicelist(self, jid=None, fetch_bundle=False): def query_devicelist(self, jid=None, fetch_bundle=False):
""" Query own devicelist from the server """ """ Query own devicelist from the server """
@@ -797,12 +837,12 @@ class OMEMOConnection:
return return
if jid is None: if jid is None:
device_query = DevicelistQuery(self.own_jid) device_query = DevicelistQuery(self.own_jid)
log.info('%s => Querry own devicelist ...', self.account) log.info('%s => Querry own devicelist ...', self._account)
self.send_with_callback(device_query, self.send_with_callback(device_query,
self.handle_devicelist_result) self.handle_devicelist_result)
else: else:
device_query = DevicelistQuery(jid) device_query = DevicelistQuery(jid)
log.info('%s => Querry devicelist from %s', self.account, jid) log.info('%s => Querry devicelist from %s', self._account, jid)
self.send_with_callback(device_query, self.send_with_callback(device_query,
self._handle_device_list_update, self._handle_device_list_update,
data={'fetch_bundle': fetch_bundle}) data={'fetch_bundle': fetch_bundle})
@@ -814,9 +854,9 @@ class OMEMOConnection:
bundle = make_bundle(self.omemo.bundle) bundle = make_bundle(self.omemo.bundle)
node = '%s%s' % (NS_BUNDLES, self.omemo.own_device_id) node = '%s%s' % (NS_BUNDLES, self.omemo.own_device_id)
log.info('%s => Publishing bundle ...', self.account) log.info('%s => Publishing bundle ...', self._account)
con = app.connections[self.account] con = app.connections[self._account]
con.get_module('PubSub').send_pb_publish( con.get_module('PubSub').send_pb_publish(
'', node, bundle, 'current', cb=self.handle_publish_result) '', node, bundle, 'current', cb=self.handle_publish_result)
@@ -829,10 +869,10 @@ class OMEMOConnection:
The stanza The stanza
""" """
if successful(stanza): if successful(stanza):
log.info('%s => Publishing bundle was successful', self.account) log.info('%s => Publishing bundle was successful', self._account)
else: else:
log.error('%s => Publishing bundle was NOT successful', log.error('%s => Publishing bundle was NOT successful',
self.account) self._account)
def handle_devicelist_result(self, stanza): def handle_devicelist_result(self, stanza):
""" If query was successful add own device to the list. """ If query was successful add own device to the list.
@@ -844,7 +884,7 @@ class OMEMOConnection:
""" """
if successful(stanza): if successful(stanza):
devices_list = list(set(unpack_device_list_update(stanza, self.account))) devices_list = list(set(unpack_device_list_update(stanza, self._account)))
if not devices_list: if not devices_list:
self.publish_own_devices_list(new=True) self.publish_own_devices_list(new=True)
return return
@@ -852,14 +892,14 @@ class OMEMOConnection:
self.omemo.set_own_devices(devices_list) self.omemo.set_own_devices(devices_list)
self.omemo.store.sessionStore.setActiveState( self.omemo.store.sessionStore.setActiveState(
devices_list, self.own_jid) devices_list, self.own_jid)
log.info('%s => Devicelistquery was successful', self.account) log.info('%s => Devicelistquery was successful', self._account)
if not self.omemo.own_device_id_published(): if not self.omemo.own_device_id_published():
# Our own device_id is not in the list, it could be # Our own device_id is not in the list, it could be
# overwritten by some other client # overwritten by some other client
self.publish_own_devices_list() self.publish_own_devices_list()
else: else:
log.error('%s => Devicelistquery was NOT successful: %s', log.error('%s => Devicelistquery was NOT successful: %s',
self.account, stanza.getError()) self._account, stanza.getError())
self.publish_own_devices_list(new=True) self.publish_own_devices_list(new=True)
@staticmethod @staticmethod
@@ -873,8 +913,12 @@ class OMEMOConnection:
log.debug('-'*15) log.debug('-'*15)
def add_additional_data(self, data): def add_additional_data(self, data):
data['encrypted'] = {'name': self.plugin.encryption_name} data['encrypted'] = {'name': ENCRYPTION_NAME}
class OMEMOError(Exception): class OMEMOError(Exception):
pass pass
def get_instance(*args, **kwargs):
return OMEMO(*args, **kwargs), 'OMEMO'

View File

@@ -71,7 +71,7 @@ except Exception as error:
if not ERROR_MSG: if not ERROR_MSG:
try: try:
from omemo.omemo_connection import OMEMOConnection from omemo.modules import omemo
except Exception as error: except Exception as error:
log.error(error) log.error(error)
ERROR_MSG = 'Error: %s' % error ERROR_MSG = 'Error: %s' % error
@@ -98,8 +98,12 @@ class OmemoPlugin(GajimPlugin):
self.allow_groupchat = True self.allow_groupchat = True
self.events_handlers = { self.events_handlers = {
'signed-in': (ged.PRECORE, self.signed_in), 'signed-in': (ged.PRECORE, self.signed_in),
} 'omemo-new-fingerprint': (ged.PRECORE, self._on_new_fingerprints),
}
self.modules = [
omemo,
# omemo_devicelist,
]
self.config_dialog = OMEMOConfigDialog(self) self.config_dialog = OMEMOConfigDialog(self)
self.gui_extension_points = { self.gui_extension_points = {
'hyperlink_handler': (self._file_decryption, None), 'hyperlink_handler': (self._file_decryption, None),
@@ -118,7 +122,6 @@ class OmemoPlugin(GajimPlugin):
SUPPORTED_PERSONAL_USER_EVENTS.append(DevicelistPEP) SUPPORTED_PERSONAL_USER_EVENTS.append(DevicelistPEP)
self.disabled_accounts = [] self.disabled_accounts = []
self.windowinstances = {} self.windowinstances = {}
self.connections = {}
self.config_default_values = {'DISABLED_ACCOUNTS': ([], ''), } self.config_default_values = {'DISABLED_ACCOUNTS': ([], ''), }
@@ -162,9 +165,6 @@ class OmemoPlugin(GajimPlugin):
return return
if account in self.disabled_accounts: if account in self.disabled_accounts:
return return
if account not in self.connections:
self.connections[account] = OMEMOConnection(account, self)
self.connections[account].signed_in(event)
def activate(self): def activate(self):
""" Method called when the Plugin is activated in the PluginManager """ Method called when the Plugin is activated in the PluginManager
@@ -174,27 +174,24 @@ class OmemoPlugin(GajimPlugin):
continue continue
if account in self.disabled_accounts: if account in self.disabled_accounts:
continue continue
self.connections[account] = OMEMOConnection(account, self) app.connections[account].get_module('OMEMO').activate()
self.connections[account].activate()
def deactivate(self): def deactivate(self):
""" Method called when the Plugin is deactivated in the PluginManager """ Method called when the Plugin is deactivated in the PluginManager
""" """
for account in self.connections: for account in app.connections:
if account == 'Local': if account == 'Local':
continue continue
self.connections[account].deactivate() app.connections[account].get_module('OMEMO').deactivate()
def _update_caps(self, account): def _update_caps(self, account):
if account == 'Local': if account == 'Local':
return return
if account not in self.connections: app.connections[account].get_module('OMEMO').update_caps(account)
self.connections[account] = OMEMOConnection(account, self)
self.connections[account].update_caps(account)
def activate_encryption(self, chat_control): def activate_encryption(self, chat_control):
if isinstance(chat_control, GroupchatControl): if isinstance(chat_control, GroupchatControl):
omemo_con = self.connections[chat_control.account] omemo_con = app.connections[chat_control.account].get_module('OMEMO')
if chat_control.room_jid not in omemo_con.groupchat: if chat_control.room_jid not in omemo_con.groupchat:
dialogs.ErrorDialog( dialogs.ErrorDialog(
_('Bad Configuration'), _('Bad Configuration'),
@@ -206,17 +203,17 @@ class OmemoPlugin(GajimPlugin):
def _message_received(self, conn, obj, callback): def _message_received(self, conn, obj, callback):
if conn.name == 'Local': if conn.name == 'Local':
return return
self.connections[conn.name].message_received(conn, obj, callback) app.connections[conn.name].get_module('OMEMO').message_received(conn, obj, callback)
def _gc_encrypt_message(self, conn, obj, callback): def _gc_encrypt_message(self, conn, obj, callback):
if conn.name == 'Local': if conn.name == 'Local':
return return
self.connections[conn.name].gc_encrypt_message(conn, obj, callback) app.connections[conn.name].get_module('OMEMO').gc_encrypt_message(conn, obj, callback)
def _encrypt_message(self, conn, obj, callback): def _encrypt_message(self, conn, obj, callback):
if conn.name == 'Local': if conn.name == 'Local':
return return
self.connections[conn.name].encrypt_message(conn, obj, callback) app.connections[conn.name].get_module('OMEMO').encrypt_message(conn, obj, callback)
def _file_decryption(self, url, kind, instance, window): def _file_decryption(self, url, kind, instance, window):
file_crypto.FileDecryption(self).hyperlink_handler( file_crypto.FileDecryption(self).hyperlink_handler(
@@ -249,14 +246,14 @@ class OmemoPlugin(GajimPlugin):
self.show_fingerprint_window(chat_control) self.show_fingerprint_window(chat_control)
def get_omemo(self, account): def get_omemo(self, account):
return self.connections[account].omemo return app.connections[account].get_module('OMEMO').omemo
def before_sendmessage(self, chat_control): def before_sendmessage(self, chat_control):
account = chat_control.account account = chat_control.account
if account == 'Local': if account == 'Local':
return return
contact = chat_control.contact contact = chat_control.contact
con = self.connections[account] con = app.connections[account].get_module('OMEMO')
self.new_fingerprints_available(chat_control) self.new_fingerprints_available(chat_control)
if isinstance(chat_control, GroupchatControl): if isinstance(chat_control, GroupchatControl):
room = chat_control.room_jid room = chat_control.room_jid
@@ -286,10 +283,13 @@ class OmemoPlugin(GajimPlugin):
log.debug('%s => Sending Message to %s', log.debug('%s => Sending Message to %s',
account, contact.jid) account, contact.jid)
def _on_new_fingerprints(self, event):
self.new_fingerprints_available(event.chat_control)
def new_fingerprints_available(self, chat_control): def new_fingerprints_available(self, chat_control):
jid = chat_control.contact.jid jid = chat_control.contact.jid
account = chat_control.account account = chat_control.account
con = self.connections[account] con = app.connections[account].get_module('OMEMO')
omemo = self.get_omemo(account) omemo = self.get_omemo(account)
if isinstance(chat_control, GroupchatControl): if isinstance(chat_control, GroupchatControl):
room_jid = chat_control.room_jid room_jid = chat_control.room_jid