Skip to content

Commit 6dc9d76

Browse files
authored
smp agent: handle client/agent version downgrades after connection was established (#1508)
1 parent 285fd93 commit 6dc9d76

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

src/Simplex/Messaging/Agent.hs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)