Automatically send heartbeats

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2021-07-13 22:43:40 +02:00
parent 62fa03959a
commit ad5822b360

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
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(jid)
encrypted = 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,10 @@ class XEP_0384(BasePlugin):
finally: finally:
asyncio.ensure_future(self._publish_bundle()) asyncio.ensure_future(self._publish_bundle())
if self.auto_heartbeat:
msg = self.make_heartbeat(jid)
asyncio.ensure_future(msg.send())
return body return body
async def encrypt_message( async def encrypt_message(
@ -630,6 +654,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 +689,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