Commit a8946797 authored by Tijmen de Mes's avatar Tijmen de Mes

Handle OTR message sessions

parent 4d87b4ee
......@@ -964,8 +964,12 @@ class ChatWidget(base_class, ui_class):
self.add_message(ChatMessage(content, sender, 'outgoing', id=id))
def _SH_ChatInputLockReleased(self, lock_type):
blink_session = self.session.blink_session
if lock_type is EncryptionLock:
self.session.chat_stream.encryption.stop()
if blink_session.chat_type is not None:
self.session.chat_stream.encryption.stop()
else:
blink_session.fake_streams.get('messages').encryption.stop()
def _SH_ComposingTimerTimeout(self):
self.composing_timer.stop()
......
......@@ -374,7 +374,16 @@ class OutgoingMessage(object):
stream = self.session.fake_streams.get('messages')
if self.content_type.lower() not in self.__disabled_imdn_content_types__:
if self.account.sms.enable_pgp and stream.can_encrypt:
content = stream.encrypt(self.content)
try:
content = stream.encrypt(self.content, self.content_type)
except Exception as e:
notification_center.post_notification('BlinkMessageDidFail',
sender=self.session,
data=NotificationData(
data=NotificationData(
code='',
reason=f"Encryption error {e}"), id=self.id))
return
self.is_secure = True
content = content if isinstance(content, bytes) else content.encode()
additional_sip_headers = []
......@@ -1113,6 +1122,20 @@ class MessageManager(object, metaclass=Singleton):
if not content_type.lower().startswith('text'):
return
if encryption is None and not x_replicated_message:
otr = blink_session.fake_streams.get('messages').check_otr(message)
if otr is not None:
message = otr
else:
return
if message.content.startswith("?OTR:") and x_replicated_message:
log.warning('Incoming message skipped, OTR encrypted, it should be handled [BUG]')
return
if message.content.startswith("?OTRv3?") and x_replicated_message:
return
if x_replicated_message or account is not blink_session.account:
history_message_data = NotificationData(remote_uri=contact.uri.uri,
message=message,
......
......@@ -1279,6 +1279,8 @@ class SMPVerificationHandler(object):
"""@type blink_session: BlinkSession"""
self.blink_session = blink_session
self.chat_stream = self.blink_session.streams.get('chat')
if self.chat_stream is None:
self.chat_stream = self.blink_session.fake_streams.get('messages')
self.delay = 0 if self.chat_stream.encryption.key_fingerprint > self.chat_stream.encryption.peer_fingerprint else 1
self.tries = 5
......@@ -1297,11 +1299,17 @@ class SMPVerificationHandler(object):
self.chat_stream = Null
def _do_smp(self):
if self.blink_session.info.streams.chat.smp_status in (SMPVerification.InProgress, SMPVerification.Succeeded, SMPVerification.Failed):
return
if isinstance(self.chat_stream, MessageStream):
if self.blink_session.info.streams.messages.smp_status in (SMPVerification.InProgress, SMPVerification.Succeeded, SMPVerification.Failed):
return
# Set SMP succeeded for message streams until it is implemented in all other clients
self.blink_session.info.streams.messages.smp_status = SMPVerification.Succeeded
else:
if self.blink_session.info.streams.chat.smp_status in (SMPVerification.InProgress, SMPVerification.Succeeded, SMPVerification.Failed):
return
audio_stream = self.audio_stream
if audio_stream.encryption.active and audio_stream.encryption.type == 'ZRTP' and audio_stream.encryption.zrtp.verified:
self.chat_stream.encryption.smp_verify(audio_stream.encryption.zrtp.sas.encode(), question=self.question)
self.chat_stream.encryption.smp_verify(audio_stream.encryption.zrtp.sas, question=self.question)
@run_in_gui_thread
def handle_notification(self, notification):
......@@ -1314,8 +1322,13 @@ class SMPVerificationHandler(object):
call_later(0, self._do_smp)
def _NH_ChatStreamSMPVerificationDidStart(self, notification):
if isinstance(self.chat_stream, MessageStream):
stream_info = self.blink_session.info.streams.messages
else:
stream_info = self.blink_session.info.streams.chat
if notification.data.originator == 'local':
self.blink_session.info.streams.chat.smp_status = SMPVerification.InProgress
stream_info.smp_status = SMPVerification.InProgress
notification.center.post_notification('BlinkSessionInfoUpdated', sender=self.blink_session, data=NotificationData(elements={'media'}))
return
if self.blink_session.info.streams.chat.smp_status is SMPVerification.Failed or notification.data.question != self.question:
......@@ -1324,22 +1337,27 @@ class SMPVerificationHandler(object):
audio_stream = self.audio_stream
if audio_stream.encryption.active and audio_stream.encryption.type == 'ZRTP' and audio_stream.encryption.zrtp.sas is not None:
self.chat_stream.encryption.smp_answer(audio_stream.encryption.zrtp.sas)
if self.blink_session.info.streams.chat.smp_status not in (SMPVerification.Succeeded, SMPVerification.Failed):
self.blink_session.info.streams.chat.smp_status = SMPVerification.InProgress
if stream_info.smp_status not in (SMPVerification.Succeeded, SMPVerification.Failed):
stream_info.smp_status = SMPVerification.InProgress
notification.center.post_notification('BlinkSessionInfoUpdated', sender=self.blink_session, data=NotificationData(elements={'media'}))
else:
self.chat_stream.encryption.smp_abort()
def _NH_ChatStreamSMPVerificationDidEnd(self, notification):
if self.blink_session.info.streams.chat.smp_status in (SMPVerification.Succeeded, SMPVerification.Failed):
if isinstance(self.chat_stream, MessageStream):
stream_info = self.blink_session.info.streams.messages
else:
stream_info = self.blink_session.info.streams.chat
if stream_info.chat.smp_status in (SMPVerification.Succeeded, SMPVerification.Failed):
return
if notification.data.status == SMPStatus.Success:
if notification.data.same_secrets:
self.blink_session.info.streams.chat.smp_status = SMPVerification.Succeeded if self.blink_session.info.streams.audio.zrtp_verified else SMPVerification.Unavailable
stream_info.smp_status = SMPVerification.Succeeded if self.blink_session.info.streams.audio.zrtp_verified else SMPVerification.Unavailable
else:
self.blink_session.info.streams.chat.smp_status = SMPVerification.Failed
stream_info.smp_status = SMPVerification.Failed
else:
self.blink_session.info.streams.chat.smp_status = SMPVerification.Unavailable
stream_info.smp_status = SMPVerification.Unavailable
if notification.data.status is SMPStatus.ProtocolError and notification.data.reason == 'startup collision':
self.tries -= 1
self.delay *= 2
......
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