@@ -2580,9 +2580,9 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), _v, sessId
25802580 mapM_ (atomically . writeTBQueue subQ) . reverse =<< readTVarIO pending
25812581 processSMP :: forall c . RcvQueue -> Connection c -> ConnData -> BrokerMsg -> TVar [ATransmission ] -> AM ()
25822582 processSMP
2583- rq@ RcvQueue {rcvId = rId, queueMode, e2ePrivKey, e2eDhSecret, status}
2583+ rq@ RcvQueue {rcvId = rId, queueMode, e2ePrivKey, e2eDhSecret, status, smpClientVersion = agreedClientVerion }
25842584 conn
2585- cData@ ConnData {connId, connAgentVersion, ratchetSyncState = rss}
2585+ cData@ ConnData {connId, connAgentVersion = agreedAgentVersion , ratchetSyncState = rss}
25862586 smpMsg
25872587 pendingMsgs =
25882588 withConnLock c connId " processSMP" $ case smpMsg of
@@ -2601,7 +2601,7 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), _v, sessId
26012601 clientMsg@ SMP. ClientMsgEnvelope {cmHeader = SMP. PubHeader phVer e2ePubKey_} <-
26022602 parseMessage msgBody
26032603 clientVRange <- asks $ smpClientVRange . config
2604- unless (phVer `isCompatible` clientVRange) . throwE $ AGENT A_VERSION
2604+ unless (phVer `isCompatible` clientVRange || phVer <= agreedClientVerion ) . throwE $ AGENT A_VERSION
26052605 case (e2eDhSecret, e2ePubKey_) of
26062606 (Nothing , Just e2ePubKey) -> do
26072607 let e2eDh = C. dh' e2ePubKey e2ePrivKey
@@ -2734,7 +2734,7 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), _v, sessId
27342734 let msgAVRange = fromMaybe (versionToRange msgAgentVersion) $ safeVersionRange (minVersion aVRange) msgAgentVersion
27352735 case msgAVRange `compatibleVersion` aVRange of
27362736 Just (Compatible av)
2737- | av > connAgentVersion -> do
2737+ | av > agreedAgentVersion -> do
27382738 withStore' c $ \ db -> setConnAgentVersion db connId av
27392739 let cData'' = cData' {connAgentVersion = av} :: ConnData
27402740 pure $ updateConnection cData'' conn'
@@ -2794,13 +2794,15 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), _v, sessId
27942794 parseMessage = liftEither . parse smpP (AGENT A_MESSAGE )
27952795
27962796 smpConfirmation :: SMP. MsgId -> Connection c -> Maybe C. APublicAuthKey -> C. PublicKeyX25519 -> Maybe (CR. SndE2ERatchetParams 'C.X448 ) -> ByteString -> VersionSMPC -> VersionSMPA -> AM ()
2797- smpConfirmation srvMsgId conn' senderKey e2ePubKey e2eEncryption encConnInfo smpClientVersion agentVersion = do
2797+ smpConfirmation srvMsgId conn' senderKey e2ePubKey e2eEncryption encConnInfo phVer agentVersion = do
27982798 logServer " <--" c srv rId $ " MSG <CONF>:" <> logSecret' srvMsgId
27992799 AgentConfig {smpClientVRange, smpAgentVRange, e2eEncryptVRange} <- asks config
28002800 let ConnData {pqSupport} = toConnData conn'
2801- unless
2802- (agentVersion `isCompatible` smpAgentVRange && smpClientVersion `isCompatible` smpClientVRange)
2803- (throwE $ AGENT A_VERSION )
2801+ -- checking agreed versions to continue connection in case of client/agent version downgrades
2802+ compatible =
2803+ (agentVersion `isCompatible` smpAgentVRange || agentVersion <= agreedAgentVersion)
2804+ && (phVer `isCompatible` smpClientVRange || phVer <= agreedClientVerion)
2805+ unless compatible $ throwE $ AGENT A_VERSION
28042806 case status of
28052807 New -> case (conn', e2eEncryption) of
28062808 -- party initiating connection
@@ -2817,7 +2819,7 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), _v, sessId
28172819 (Right agentMsgBody, CR. SMDNoChange ) ->
28182820 parseMessage agentMsgBody >>= \ case
28192821 AgentConnInfoReply smpQueues connInfo -> do
2820- processConf connInfo SMPConfirmation {senderKey, e2ePubKey, connInfo, smpReplyQueues = L. toList smpQueues, smpClientVersion}
2822+ processConf connInfo SMPConfirmation {senderKey, e2ePubKey, connInfo, smpReplyQueues = L. toList smpQueues, smpClientVersion = phVer }
28212823 withStore' c $ \ db -> updateRcvMsgHash db connId 1 (InternalRcvId 0 ) (C. sha256Hash agentMsgBody)
28222824 _ -> prohibited " conf: not AgentConnInfoReply" -- including AgentConnInfo, that is prohibited here in v2
28232825 where
@@ -2851,7 +2853,7 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), _v, sessId
28512853 notify $ INFO pqSupport connInfo
28522854 let dhSecret = C. dh' e2ePubKey e2ePrivKey
28532855 withStore' c $ \ db -> do
2854- setRcvQueueConfirmedE2E db rq dhSecret $ min v' smpClientVersion
2856+ setRcvQueueConfirmedE2E db rq dhSecret $ min v' phVer
28552857 updateRcvMsgHash db connId 1 (InternalRcvId 0 ) (C. sha256Hash agentMsgBody)
28562858 case senderKey of
28572859 Just k -> enqueueCmd $ ICDuplexSecure rId k
0 commit comments