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

[omemo] Set devices inactive after 300 unacknowledged messages

parent d463caf0
......@@ -19,6 +19,8 @@ from collections import defaultdict
from gajim.common import app
from omemo.backend.util import UNACKNOWLEDGED_COUNT
log = logging.getLogger('gajim.plugin_system.omemo')
......@@ -39,6 +41,15 @@ class DeviceManager:
self.add_device(jid, device)
def update_devicelist(self, jid, devicelist):
for device in list(devicelist):
if device == self.own_device:
continue
count = self._storage.getUnacknowledgedCount(jid, device)
if count > UNACKNOWLEDGED_COUNT:
log.warning('Ignore device because of %s unacknowledged'
' messages: %s %s', count, jid, device)
devicelist.remove(device)
self.__device_store[jid] = set(devicelist)
log.info('Saved devices for %s', jid)
self._storage.setActiveState(jid, devicelist)
......@@ -60,6 +71,10 @@ class DeviceManager:
def add_device(self, jid, device):
self.__device_store[jid].add(device)
def remove_device(self, jid, device):
self.__device_store[jid].discard(device)
self._storage.setInactive(jid, device)
def get_devices(self, jid, without_self=False):
devices = set(self.__device_store[jid])
if without_self:
......
......@@ -320,16 +320,22 @@ class LiteAxolotlStore(AxolotlStore):
', '.join(['?'] * len(recipientIds)))
return self._con.execute(query, recipientIds).fetchall()
def setActiveState(self, jid, deviceList):
def setActiveState(self, jid, devicelist):
query = '''UPDATE sessions SET active = 1
WHERE recipient_id = ? AND device_id IN ({})'''.format(
', '.join(['?'] * len(deviceList)))
self._con.execute(query, (jid,) + tuple(deviceList))
', '.join(['?'] * len(devicelist)))
self._con.execute(query, (jid,) + tuple(devicelist))
query = '''UPDATE sessions SET active = 0
WHERE recipient_id = ? AND device_id NOT IN ({})'''.format(
', '.join(['?'] * len(deviceList)))
self._con.execute(query, (jid,) + tuple(deviceList))
', '.join(['?'] * len(devicelist)))
self._con.execute(query, (jid,) + tuple(devicelist))
self._con.commit()
def setInactive(self, jid, device_id):
query = '''UPDATE sessions SET active = 0
WHERE recipient_id = ? AND device_id = ?'''
self._con.execute(query, (jid, device_id))
self._con.commit()
def getInactiveSessionsKeys(self, recipientId):
......@@ -515,3 +521,8 @@ class LiteAxolotlStore(AxolotlStore):
WHERE recipient_id = ? AND public_key = ?'''
self._con.execute(query, (timestamp, recipient_id, identity_key))
self._con.commit()
def getUnacknowledgedCount(self, recipient_id, device_id):
record = self.loadSession(recipient_id, device_id)
state = record.getSessionState()
return state.getSenderChainKey().getIndex()
......@@ -42,6 +42,7 @@ from omemo.backend.util import DEFAULT_PREKEY_AMOUNT
from omemo.backend.util import MIN_PREKEY_AMOUNT
from omemo.backend.util import SPK_CYCLE_TIME
from omemo.backend.util import SPK_ARCHIVE_TIME
from omemo.backend.util import UNACKNOWLEDGED_COUNT
log = logging.getLogger('gajim.plugin_system.omemo')
......@@ -172,6 +173,12 @@ class OmemoState(DeviceManager):
whisper_messages = defaultdict(dict)
for jid_, device in devices_for_encryption:
count = self._storage.getUnacknowledgedCount(jid_, device)
if count >= UNACKNOWLEDGED_COUNT:
log.warning('Set device inactive %s because of %s '
'unacknowledged messages', device, count)
self.remove_device(jid_, device)
try:
whisper_messages[jid_][device] = self._get_whisper_message(
jid_, device, result.key)
......
......@@ -22,6 +22,7 @@ DEFAULT_PREKEY_AMOUNT = 100
MIN_PREKEY_AMOUNT = 80
SPK_ARCHIVE_TIME = 86400 * 15 # 15 Days
SPK_CYCLE_TIME = 86400 # 24 Hours
UNACKNOWLEDGED_COUNT = 300
class Trust(IntEnum):
......
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