@@ -2396,9 +2396,9 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), _v, sessId
23962396 mapM_ (atomically . writeTBQueue subQ) . reverse =<< readTVarIO pending
23972397 processSMP :: forall c . RcvQueue -> Connection c -> ConnData -> BrokerMsg -> TVar [ATransmission ] -> AM ()
23982398 processSMP
2399- rq@ RcvQueue {rcvId = rId, sndSecure, e2ePrivKey, e2eDhSecret, status}
2399+ rq@ RcvQueue {rcvId = rId, sndSecure, e2ePrivKey, e2eDhSecret, status, smpClientVersion = agreedClientVerion }
24002400 conn
2401- cData@ ConnData {connId, connAgentVersion, ratchetSyncState = rss}
2401+ cData@ ConnData {connId, connAgentVersion = agreedAgentVersion , ratchetSyncState = rss}
24022402 smpMsg
24032403 pendingMsgs =
24042404 withConnLock c connId " processSMP" $ case smpMsg of
@@ -2417,7 +2417,7 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), _v, sessId
24172417 clientMsg@ SMP. ClientMsgEnvelope {cmHeader = SMP. PubHeader phVer e2ePubKey_} <-
24182418 parseMessage msgBody
24192419 clientVRange <- asks $ smpClientVRange . config
2420- unless (phVer `isCompatible` clientVRange) . throwE $ AGENT A_VERSION
2420+ unless (phVer `isCompatible` clientVRange || phVer <= agreedClientVerion ) . throwE $ AGENT A_VERSION
24212421 case (e2eDhSecret, e2ePubKey_) of
24222422 (Nothing , Just e2ePubKey) -> do
24232423 let e2eDh = C. dh' e2ePubKey e2ePrivKey
@@ -2550,7 +2550,7 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), _v, sessId
25502550 let msgAVRange = fromMaybe (versionToRange msgAgentVersion) $ safeVersionRange (minVersion aVRange) msgAgentVersion
25512551 case msgAVRange `compatibleVersion` aVRange of
25522552 Just (Compatible av)
2553- | av > connAgentVersion -> do
2553+ | av > agreedAgentVersion -> do
25542554 withStore' c $ \ db -> setConnAgentVersion db connId av
25552555 let cData'' = cData' {connAgentVersion = av} :: ConnData
25562556 pure $ updateConnection cData'' conn'
@@ -2610,13 +2610,15 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), _v, sessId
26102610 parseMessage = liftEither . parse smpP (AGENT A_MESSAGE )
26112611
26122612 smpConfirmation :: SMP. MsgId -> Connection c -> Maybe C. APublicAuthKey -> C. PublicKeyX25519 -> Maybe (CR. SndE2ERatchetParams 'C.X448 ) -> ByteString -> VersionSMPC -> VersionSMPA -> AM ()
2613- smpConfirmation srvMsgId conn' senderKey e2ePubKey e2eEncryption encConnInfo smpClientVersion agentVersion = do
2613+ smpConfirmation srvMsgId conn' senderKey e2ePubKey e2eEncryption encConnInfo phVer agentVersion = do
26142614 logServer " <--" c srv rId $ " MSG <CONF>:" <> logSecret' srvMsgId
26152615 AgentConfig {smpClientVRange, smpAgentVRange, e2eEncryptVRange} <- asks config
26162616 let ConnData {pqSupport} = toConnData conn'
2617- unless
2618- (agentVersion `isCompatible` smpAgentVRange && smpClientVersion `isCompatible` smpClientVRange)
2619- (throwE $ AGENT A_VERSION )
2617+ -- checking agreed versions to continue connection in case of client/agent version downgrades
2618+ compatible =
2619+ (agentVersion `isCompatible` smpAgentVRange || agentVersion <= agreedAgentVersion)
2620+ && (phVer `isCompatible` smpClientVRange || phVer <= agreedClientVerion)
2621+ unless compatible $ throwE $ AGENT A_VERSION
26202622 case status of
26212623 New -> case (conn', e2eEncryption) of
26222624 -- party initiating connection
@@ -2633,7 +2635,7 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), _v, sessId
26332635 (Right agentMsgBody, CR. SMDNoChange ) ->
26342636 parseMessage agentMsgBody >>= \ case
26352637 AgentConnInfoReply smpQueues connInfo -> do
2636- processConf connInfo SMPConfirmation {senderKey, e2ePubKey, connInfo, smpReplyQueues = L. toList smpQueues, smpClientVersion}
2638+ processConf connInfo SMPConfirmation {senderKey, e2ePubKey, connInfo, smpReplyQueues = L. toList smpQueues, smpClientVersion = phVer }
26372639 withStore' c $ \ db -> updateRcvMsgHash db connId 1 (InternalRcvId 0 ) (C. sha256Hash agentMsgBody)
26382640 _ -> prohibited " conf: not AgentConnInfoReply" -- including AgentConnInfo, that is prohibited here in v2
26392641 where
@@ -2667,7 +2669,7 @@ processSMPTransmissions c@AgentClient {subQ} (tSess@(userId, srv, _), _v, sessId
26672669 notify $ INFO pqSupport connInfo
26682670 let dhSecret = C. dh' e2ePubKey e2ePrivKey
26692671 withStore' c $ \ db -> do
2670- setRcvQueueConfirmedE2E db rq dhSecret $ min v' smpClientVersion
2672+ setRcvQueueConfirmedE2E db rq dhSecret $ min v' phVer
26712673 updateRcvMsgHash db connId 1 (InternalRcvId 0 ) (C. sha256Hash agentMsgBody)
26722674 case senderKey of
26732675 Just k -> enqueueCmd $ ICDuplexSecure rId k
0 commit comments