mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
core: add chat items to indicate decryption failures due to ratchets being out of sync (#2175)
* core: add chat items to indicate decryption failures due to ratchets being out of sync * show ratchet errors in chat items, show all integrity errors * show decryption errors, tests * ios: chat items, remove item for duplicate messages * android: decryption errors chat items * eol
This commit is contained in:
committed by
GitHub
parent
13cf1cc004
commit
aea526f69d
+46
-3
@@ -47,6 +47,7 @@ import Data.Time (NominalDiffTime, addUTCTime, defaultTimeLocale, formatTime)
|
||||
import Data.Time.Clock (UTCTime, diffUTCTime, getCurrentTime, nominalDiffTimeToSeconds)
|
||||
import Data.Time.Clock.System (SystemTime, systemToUTCTime)
|
||||
import Data.Time.LocalTime (getCurrentTimeZone, getZonedTime)
|
||||
import Data.Word (Word32)
|
||||
import qualified Database.SQLite.Simple as DB
|
||||
import Simplex.Chat.Archive
|
||||
import Simplex.Chat.Call
|
||||
@@ -2630,6 +2631,19 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do
|
||||
ERR err -> do
|
||||
toView $ CRChatError (Just user) (ChatErrorAgent err $ Just connEntity)
|
||||
when (corrId /= "") $ withCompletedCommand conn agentMsg $ \_cmdData -> pure ()
|
||||
forM_ (agentMsgDecryptError err) $ \e@(mde, n) -> do
|
||||
ci_ <- withStore $ \db ->
|
||||
getDirectChatItemsLast db user contactId 1 ""
|
||||
>>= liftIO
|
||||
. mapM (\(ci, content') -> updateDirectChatItem' db user contactId ci content' False Nothing)
|
||||
. (mdeUpdatedCI e <=< headMaybe)
|
||||
case ci_ of
|
||||
Just ci -> toView $ CRChatItemUpdated user (AChatItem SCTDirect SMDRcv (DirectChat ct) ci)
|
||||
_ -> createInternalChatItem user (CDDirectRcv ct) (CIRcvDecryptionError mde n) Nothing
|
||||
where
|
||||
headMaybe = \case
|
||||
x : _ -> Just x
|
||||
_ -> Nothing
|
||||
-- TODO add debugging output
|
||||
_ -> pure ()
|
||||
|
||||
@@ -2791,9 +2805,40 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do
|
||||
ERR err -> do
|
||||
toView $ CRChatError (Just user) (ChatErrorAgent err $ Just connEntity)
|
||||
when (corrId /= "") $ withCompletedCommand conn agentMsg $ \_cmdData -> pure ()
|
||||
forM_ (agentMsgDecryptError err) $ \e@(mde, n) -> do
|
||||
ci_ <- withStore $ \db ->
|
||||
getGroupMemberChatItemLast db user groupId (groupMemberId' m)
|
||||
>>= liftIO
|
||||
. mapM (\(ci, content') -> updateGroupChatItem db user groupId ci content' False Nothing)
|
||||
. mdeUpdatedCI e
|
||||
case ci_ of
|
||||
Just ci -> toView $ CRChatItemUpdated user (AChatItem SCTGroup SMDRcv (GroupChat gInfo) ci)
|
||||
_ -> createInternalChatItem user (CDGroupRcv gInfo m) (CIRcvDecryptionError mde n) Nothing
|
||||
-- TODO add debugging output
|
||||
_ -> pure ()
|
||||
|
||||
agentMsgDecryptError :: AgentErrorType -> Maybe (MsgDecryptError, Word32)
|
||||
agentMsgDecryptError = \case
|
||||
AGENT (A_CRYPTO RATCHET_HEADER) -> Just (MDERatchetHeader, 1)
|
||||
AGENT (A_CRYPTO (RATCHET_EARLIER n)) -> Just (MDEEarlier, n + 1) -- 1 is added to account for the message that has A_DUPLICATE error
|
||||
AGENT (A_CRYPTO (RATCHET_SKIPPED n)) -> Just (MDETooManySkipped, n)
|
||||
-- we are not treating this as decryption error, as in many cases it happens as the result of duplicate or redundant delivery,
|
||||
-- and we don't have a way to differentiate.
|
||||
-- we could store the hashes of past messages in the agent, or delaying message deletion after ACK
|
||||
-- A_DUPLICATE -> Nothing
|
||||
_ -> Nothing
|
||||
|
||||
mdeUpdatedCI :: (MsgDecryptError, Word32) -> CChatItem c -> Maybe (ChatItem c 'MDRcv, CIContent 'MDRcv)
|
||||
mdeUpdatedCI (mde', n') (CChatItem _ ci@ChatItem {content = CIRcvDecryptionError mde n})
|
||||
| mde == mde' = case mde of
|
||||
MDERatchetHeader -> r (n + n')
|
||||
MDEEarlier -> r n -- the first error in a sequence has the largest number – it's the number of messages to receive to catch up, keeping it
|
||||
MDETooManySkipped -> r n' -- the numbers are not added as sequential MDETooManySkipped will have it incremented by 1
|
||||
| otherwise = Nothing
|
||||
where
|
||||
r n'' = Just (ci, CIRcvDecryptionError mde n'')
|
||||
mdeUpdatedCI _ _ = Nothing
|
||||
|
||||
processSndFileConn :: ACommand 'Agent e -> ConnectionEntity -> Connection -> SndFileTransfer -> m ()
|
||||
processSndFileConn agentMsg connEntity conn ft@SndFileTransfer {fileId, fileName, fileStatus} =
|
||||
case agentMsg of
|
||||
@@ -3469,9 +3514,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do
|
||||
checkIntegrityCreateItem :: forall c. ChatTypeI c => ChatDirection c 'MDRcv -> MsgMeta -> m ()
|
||||
checkIntegrityCreateItem cd MsgMeta {integrity, broker = (_, brokerTs)} = case integrity of
|
||||
MsgOk -> pure ()
|
||||
MsgError e -> case e of
|
||||
MsgSkipped {} -> createInternalChatItem user cd (CIRcvIntegrityError e) (Just brokerTs)
|
||||
_ -> toView $ CRMsgIntegrityError user e
|
||||
MsgError e -> createInternalChatItem user cd (CIRcvIntegrityError e) (Just brokerTs)
|
||||
|
||||
xInfo :: Contact -> Profile -> m ()
|
||||
xInfo c@Contact {profile = p} p' = unless (fromLocalProfile p == p') $ do
|
||||
|
||||
Reference in New Issue
Block a user