Commit b2be4c91 authored by Philipp Hörist's avatar Philipp Hörist
Browse files

[omemo] Query devices if we have none

- PEP is not reliable enough for now, so we have to use this as
fallback
parent 13c9ba9b
...@@ -121,7 +121,7 @@ class OMEMOConnection: ...@@ -121,7 +121,7 @@ class OMEMOConnection:
log.debug('%s => Announce Support after Sign In', self.account) log.debug('%s => Announce Support after Sign In', self.account)
self.query_for_bundles = [] self.query_for_bundles = []
self.publish_bundle() self.publish_bundle()
self.query_own_devicelist() self.query_devicelist()
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
...@@ -136,7 +136,7 @@ class OMEMOConnection: ...@@ -136,7 +136,7 @@ class OMEMOConnection:
self.account) self.account)
self.query_for_bundles = [] self.query_for_bundles = []
self.publish_bundle() self.publish_bundle()
self.query_own_devicelist() self.query_devicelist()
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
...@@ -518,16 +518,34 @@ class OMEMOConnection: ...@@ -518,16 +518,34 @@ 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':
return False return
self._handle_device_list_update(None, event.stanza)
# Dont 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
device ids.
Parameters
----------
conn : nbxmpp.NonBlockingClient
stanza: nbxmpp.Iq
fetch_bundle: If True, bundles are fetched for the device ids
"""
devices_list = list(set(unpack_device_list_update(event.stanza, devices_list = list(set(unpack_device_list_update(stanza,
event.conn.name))) self.account)))
contact_jid = app.get_jid_without_resource(event.fjid) 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)
...@@ -561,11 +579,11 @@ class OMEMOConnection: ...@@ -561,11 +579,11 @@ class OMEMOConnection:
if contact_jid in self.query_for_bundles: if contact_jid in self.query_for_bundles:
self.query_for_bundles.remove(contact_jid) self.query_for_bundles.remove(contact_jid)
if fetch_bundle:
self.are_keys_missing(contact_jid)
# Enable Encryption on receiving first Device List # Enable Encryption on receiving first Device List
# TODO # TODO
return True
def publish_own_devices_list(self, new=False): def publish_own_devices_list(self, new=False):
""" Get all currently known own active device ids and publish them """ Get all currently known own active device ids and publish them
...@@ -690,12 +708,19 @@ class OMEMOConnection: ...@@ -690,12 +708,19 @@ class OMEMOConnection:
if ctrl: if ctrl:
self.plugin.new_fingerprints_available(ctrl) self.plugin.new_fingerprints_available(ctrl)
def query_own_devicelist(self): def query_devicelist(self, jid=None, fetch_bundle=False):
""" Query own devicelist from the server """ """ Query own devicelist from the server """
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.handle_devicelist_result) self.send_with_callback(device_query,
self.handle_devicelist_result)
else:
device_query = DevicelistQuery(jid)
log.info('%s => Querry devicelist from %s', self.account, jid)
self.send_with_callback(device_query,
self._handle_device_list_update,
data={'fetch_bundle': fetch_bundle})
def publish_bundle(self): def publish_bundle(self):
""" Publish our bundle information to the PEP node """ """ Publish our bundle information to the PEP node """
......
...@@ -23,6 +23,7 @@ the Gajim-OMEMO plugin. If not, see <http://www.gnu.org/licenses/>. ...@@ -23,6 +23,7 @@ the Gajim-OMEMO plugin. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
import binascii import binascii
import threading import threading
from enum import IntEnum, unique
from gi.repository import GLib from gi.repository import GLib
...@@ -73,6 +74,12 @@ if not ERROR_MSG: ...@@ -73,6 +74,12 @@ if not ERROR_MSG:
# pylint: disable=attribute-defined-outside-init # pylint: disable=attribute-defined-outside-init
@unique
class UserMessages(IntEnum):
QUERY_DEVICES = 0
NO_FINGERPRINTS = 1
class OmemoPlugin(GajimPlugin): class OmemoPlugin(GajimPlugin):
def init(self): def init(self):
""" Init """ """ Init """
...@@ -206,6 +213,7 @@ class OmemoPlugin(GajimPlugin): ...@@ -206,6 +213,7 @@ class OmemoPlugin(GajimPlugin):
def before_sendmessage(self, chat_control): def before_sendmessage(self, chat_control):
account = chat_control.account account = chat_control.account
contact = chat_control.contact contact = chat_control.contact
con = self.connections[account]
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
...@@ -215,17 +223,24 @@ class OmemoPlugin(GajimPlugin): ...@@ -215,17 +223,24 @@ class OmemoPlugin(GajimPlugin):
real_jid = con.groupchat[room][nick] real_jid = con.groupchat[room][nick]
if real_jid == own_jid: if real_jid == own_jid:
continue continue
if not self.connections[account].are_keys_missing(real_jid): if not con.are_keys_missing(real_jid):
missing = False missing = False
if missing: if missing:
log.debug('%s => No Trusted Fingerprints for %s', log.info('%s => No Trusted Fingerprints for %s',
account, room) account, room)
self.no_trusted_fingerprints_warning(chat_control) self.print_message(chat_control, UserMessages.NO_FINGERPRINTS)
else: else:
if self.connections[account].are_keys_missing(contact.jid): # check if we have devices for the contact
log.debug('%s => No Trusted Fingerprints for %s', if not self.get_omemo(account).device_list_for(contact.jid):
account, contact.jid) con.query_devicelist(contact.jid, True)
self.no_trusted_fingerprints_warning(chat_control) self.print_message(chat_control, UserMessages.QUERY_DEVICES)
chat_control.sendmessage = False
return
# check if bundles are missing for some devices
if con.are_keys_missing(contact.jid):
log.info('%s => No Trusted Fingerprints for %s',
account, contact.jid)
self.print_message(chat_control, UserMessages.NO_FINGERPRINTS)
chat_control.sendmessage = False chat_control.sendmessage = False
else: else:
log.debug('%s => Sending Message to %s', log.debug('%s => Sending Message to %s',
...@@ -277,7 +292,13 @@ class OmemoPlugin(GajimPlugin): ...@@ -277,7 +292,13 @@ class OmemoPlugin(GajimPlugin):
omemo.store.setShownFingerprints(fingerprints) omemo.store.setShownFingerprints(fingerprints)
@staticmethod @staticmethod
def no_trusted_fingerprints_warning(chat_control): def print_message(chat_control, kind):
msg = "To send an encrypted message, you have to " \ msg = None
"first trust the fingerprint of your contact!" if kind == UserMessages.QUERY_DEVICES:
msg = _('No devices found. Query in progress...')
elif kind == UserMessages.NO_FINGERPRINTS:
msg = _('To send an encrypted message, you have to '
'first trust the fingerprint of your contact!')
if msg is None:
return
chat_control.print_conversation_line(msg, 'status', '', None) chat_control.print_conversation_line(msg, 'status', '', None)
...@@ -140,7 +140,7 @@ class BundleInformationAnnouncement(Iq): ...@@ -140,7 +140,7 @@ class BundleInformationAnnouncement(Iq):
class DevicelistQuery(Iq): class DevicelistQuery(Iq):
def __init__(self, contact_jid,): def __init__(self, contact_jid):
id_ = app.get_an_id() id_ = app.get_an_id()
attrs = {'id': id_} attrs = {'id': id_}
Iq.__init__(self, typ='get', attrs=attrs, to=contact_jid) Iq.__init__(self, typ='get', attrs=attrs, to=contact_jid)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment