Merge branch 'heartbeat' into 'master'

Automatically send heartbeats

See merge request poezio/slixmpp-omemo!10
This commit is contained in:
Maxime Buquet 2021-07-15 00:43:30 +02:00
commit 3ac03796dc

View file

@ -117,7 +117,8 @@ def _generate_encrypted_payload(encrypted) -> Encrypted:
tag['header']['sid'] = str(encrypted['sid']) tag['header']['sid'] = str(encrypted['sid'])
tag['header']['iv']['value'] = b64enc(encrypted['iv']) tag['header']['iv']['value'] = b64enc(encrypted['iv'])
tag['payload']['value'] = b64enc(encrypted['payload']) if 'payload' in encrypted:
tag['payload']['value'] = b64enc(encrypted['payload'])
for bare_jid, devices in encrypted['keys'].items(): for bare_jid, devices in encrypted['keys'].items():
for rid, device in devices.items(): for rid, device in devices.items():
@ -197,6 +198,7 @@ class XEP_0384(BasePlugin):
'storage_backend': None, 'storage_backend': None,
'otpk_policy': DefaultOTPKPolicy, 'otpk_policy': DefaultOTPKPolicy,
'omemo_backend': SignalBackend, 'omemo_backend': SignalBackend,
'auto_heartbeat': True,
'heartbeat_after': 53, 'heartbeat_after': 53,
# TODO: 'drop_inactive_after': 300, # TODO: 'drop_inactive_after': 300,
} }
@ -536,6 +538,24 @@ class XEP_0384(BasePlugin):
lengths = map(lambda d_l: d_l[1], receiving_chain_lengths) lengths = map(lambda d_l: d_l[1], receiving_chain_lengths)
return max(lengths, default=0) > self.heartbeat_after return max(lengths, default=0) > self.heartbeat_after
async def make_heartbeat(self, jid: JID) -> Message:
"""
Returns a heartbeat message.
This is mainly used to tell receiving clients that our device is
still active. This is an empty key transport message of which we
won't use the generated shared secret.
"""
msg = self.xmpp.make_message(mto=jid)
encrypted = await self.encrypt_key_transport_message(
plaintext=None,
recipients=[jid],
expect_problems=None,
)
msg.append(encrypted)
return msg
def trust(self, jid: JID, device_id: int, ik: bytes) -> None: def trust(self, jid: JID, device_id: int, ik: bytes) -> None:
self._omemo.setTrust(jid.bare, device_id, ik, True) self._omemo.setTrust(jid.bare, device_id, ik, True)
@ -623,6 +643,12 @@ class XEP_0384(BasePlugin):
finally: finally:
asyncio.ensure_future(self._publish_bundle()) asyncio.ensure_future(self._publish_bundle())
if self.auto_heartbeat and self.should_heartbeat():
async def send_heartbeat():
msg = await self.make_heartbeat(JID(jid))
msg.send()
asyncio.ensure_future(send_heartbeat())
return body return body
async def encrypt_message( async def encrypt_message(
@ -630,6 +656,18 @@ class XEP_0384(BasePlugin):
plaintext: str, plaintext: str,
recipients: List[JID], recipients: List[JID],
expect_problems: Optional[Dict[JID, List[int]]] = None, expect_problems: Optional[Dict[JID, List[int]]] = None,
) -> Encrypted:
return await self.encrypt_key_transport_message(
plaintext.encode('utf-8'),
recipients,
expect_problems,
)
async def encrypt_key_transport_message(
self,
plaintext: Optional[bytes],
recipients: List[JID],
expect_problems: Optional[Dict[JID, List[int]]] = None,
) -> Encrypted: ) -> Encrypted:
""" """
Returns an encrypted payload to be placed into a message. Returns an encrypted payload to be placed into a message.
@ -653,12 +691,19 @@ class XEP_0384(BasePlugin):
expect_problems = {jid.bare: did for (jid, did) in expect_problems.items()} expect_problems = {jid.bare: did for (jid, did) in expect_problems.items()}
try: try:
encrypted = self._omemo.encryptMessage( if plaintext is not None:
recipients, encrypted = self._omemo.encryptMessage(
plaintext.encode('utf-8'), recipients,
self.bundles, plaintext,
expect_problems=expect_problems, self.bundles,
) expect_problems=expect_problems,
)
else:
encrypted = self._omemo.encryptKeyTransportMessage(
recipients,
self.bundles,
expect_problems=expect_problems,
)
return _generate_encrypted_payload(encrypted) return _generate_encrypted_payload(encrypted)
except omemo.exceptions.EncryptionProblemsException as exception: except omemo.exceptions.EncryptionProblemsException as exception:
errors = exception.problems errors = exception.problems