Skip to content

Commit 6a90751

Browse files
authored
xftp server: use recipient ID in control port to delete and block files, smp server: fix version negotiation (#1434)
* xftp server: use recipient ID in control port to delete and block files * cap smp proxy agent version at 10 * version * fix prometheus * fix * remove old version support * log connection parameter on error * tests * log sent command tag * log error and client version * cap proxy version for previous destination server * comment, test * remove logging tag * remove logs * version * SMP version 14 * version * remove comments * version
1 parent 488c708 commit 6a90751

File tree

15 files changed

+154
-128
lines changed

15 files changed

+154
-128
lines changed

src/Simplex/FileTransfer/Server.hs

+8-8
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,13 @@ xftpServer cfg@XFTPServerConfig {xftpPort, transportConfig, inactiveClientExpira
287287
CPDelete fileId -> withUserRole $ unliftIO u $ do
288288
fs <- asks store
289289
r <- runExceptT $ do
290-
(fr, _) <- ExceptT $ atomically $ getFile fs SFSender fileId
290+
(fr, _) <- ExceptT $ atomically $ getFile fs SFRecipient fileId
291291
ExceptT $ deleteServerFile_ fr
292292
liftIO . hPutStrLn h $ either (\e -> "error: " <> show e) (\() -> "ok") r
293293
CPBlock fileId info -> withUserRole $ unliftIO u $ do
294294
fs <- asks store
295295
r <- runExceptT $ do
296-
(fr, _) <- ExceptT $ atomically $ getFile fs SFSender fileId
296+
(fr, _) <- ExceptT $ atomically $ getFile fs SFRecipient fileId
297297
ExceptT $ blockServerFile fr info
298298
liftIO . hPutStrLn h $ either (\e -> "error: " <> show e) (\() -> "ok") r
299299
CPHelp -> hPutStrLn h "commands: stats-rts, delete, help, quit"
@@ -540,12 +540,12 @@ blockServerFile fr@FileRec {senderId} info = do
540540

541541
deleteOrBlockServerFile_ :: FileRec -> (FileServerStats -> IORef Int) -> (FileStore -> STM (Either XFTPErrorType ())) -> M (Either XFTPErrorType ())
542542
deleteOrBlockServerFile_ FileRec {filePath, fileInfo} stat storeAction = runExceptT $ do
543-
path <- readTVarIO filePath
544-
stats <- asks serverStats
545-
ExceptT $ first (\(_ :: SomeException) -> FILE_IO) <$> try (forM_ path $ \p -> whenM (doesFileExist p) (removeFile p >> deletedStats stats))
546-
st <- asks store
547-
void $ atomically $ storeAction st
548-
lift $ incFileStat stat
543+
path <- readTVarIO filePath
544+
stats <- asks serverStats
545+
ExceptT $ first (\(_ :: SomeException) -> FILE_IO) <$> try (forM_ path $ \p -> whenM (doesFileExist p) (removeFile p >> deletedStats stats))
546+
st <- asks store
547+
void $ atomically $ storeAction st
548+
lift $ incFileStat stat
549549
where
550550
deletedStats stats = do
551551
liftIO $ atomicModifyIORef'_ (filesCount stats) (subtract 1)

src/Simplex/FileTransfer/Transport.hs

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ supportedFileServerVRange :: VersionRangeXFTP
102102
supportedFileServerVRange = mkVersionRange initialXFTPVersion currentXFTPVersion
103103

104104
-- XFTP protocol does not use this handshake method
105-
xftpClientHandshakeStub :: c -> Maybe C.KeyPairX25519 -> C.KeyHash -> VersionRangeXFTP -> ExceptT TransportError IO (THandle XFTPVersion c 'TClient)
106-
xftpClientHandshakeStub _c _ks _keyHash _xftpVRange = throwE TEVersion
105+
xftpClientHandshakeStub :: c -> Maybe C.KeyPairX25519 -> C.KeyHash -> VersionRangeXFTP -> Bool -> ExceptT TransportError IO (THandle XFTPVersion c 'TClient)
106+
xftpClientHandshakeStub _c _ks _keyHash _xftpVRange _proxyServer = throwE TEVersion
107107

108108
supportedXFTPhandshakes :: [ALPN]
109109
supportedXFTPhandshakes = ["xftp/1"]

src/Simplex/Messaging/Client.hs

+14-8
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ data PClient v err msg = PClient
171171
timeoutErrorCount :: TVar Int,
172172
clientCorrId :: TVar ChaChaDRG,
173173
sentCommands :: TMap CorrId (Request err msg),
174-
sndQ :: TBQueue (Maybe (TVar Bool), ByteString),
174+
sndQ :: TBQueue (Maybe (Request err msg), ByteString),
175175
rcvQ :: TBQueue (NonEmpty (SignedTransmission err msg)),
176176
msgQ :: Maybe (TBQueue (ServerTransmissionBatch v err msg))
177177
}
@@ -406,6 +406,8 @@ data ProtocolClientConfig v = ProtocolClientConfig
406406
serverVRange :: VersionRange v,
407407
-- | agree shared session secret (used in SMP proxy for additional encryption layer)
408408
agreeSecret :: Bool,
409+
-- | Whether connecting client is a proxy server. See comment in ClientHandshake
410+
proxyServer :: Bool,
409411
-- | send SNI to server, False for SMP
410412
useSNI :: Bool
411413
}
@@ -420,6 +422,7 @@ defaultClientConfig clientALPN useSNI serverVRange =
420422
clientALPN,
421423
serverVRange,
422424
agreeSecret = False,
425+
proxyServer = False,
423426
useSNI
424427
}
425428
{-# INLINE defaultClientConfig #-}
@@ -489,7 +492,7 @@ type TransportSession msg = (UserId, ProtoServer msg, Maybe ByteString)
489492
-- A single queue can be used for multiple 'SMPClient' instances,
490493
-- as 'SMPServerTransmission' includes server information.
491494
getProtocolClient :: forall v err msg. Protocol v err msg => TVar ChaChaDRG -> TransportSession msg -> ProtocolClientConfig v -> Maybe (TBQueue (ServerTransmissionBatch v err msg)) -> UTCTime -> (ProtocolClient v err msg -> IO ()) -> IO (Either (ProtocolClientError err) (ProtocolClient v err msg))
492-
getProtocolClient g transportSession@(_, srv, _) cfg@ProtocolClientConfig {qSize, networkConfig, clientALPN, serverVRange, agreeSecret, useSNI} msgQ proxySessTs disconnected = do
495+
getProtocolClient g transportSession@(_, srv, _) cfg@ProtocolClientConfig {qSize, networkConfig, clientALPN, serverVRange, agreeSecret, proxyServer, useSNI} msgQ proxySessTs disconnected = do
493496
case chooseTransportHost networkConfig (host srv) of
494497
Right useHost ->
495498
(getCurrentTime >>= mkProtocolClient useHost >>= runClient useTransport useHost)
@@ -548,7 +551,7 @@ getProtocolClient g transportSession@(_, srv, _) cfg@ProtocolClientConfig {qSize
548551
client :: forall c. Transport c => TProxy c -> PClient v err msg -> TMVar (Either (ProtocolClientError err) (ProtocolClient v err msg)) -> c -> IO ()
549552
client _ c cVar h = do
550553
ks <- if agreeSecret then Just <$> atomically (C.generateKeyPair g) else pure Nothing
551-
runExceptT (protocolClientHandshake @v @err @msg h ks (keyHash srv) serverVRange) >>= \case
554+
runExceptT (protocolClientHandshake @v @err @msg h ks (keyHash srv) serverVRange proxyServer) >>= \case
552555
Left e -> atomically . putTMVar cVar . Left $ PCETransportError e
553556
Right th@THandle {params} -> do
554557
sessionTs <- getCurrentTime
@@ -563,9 +566,12 @@ getProtocolClient g transportSession@(_, srv, _) cfg@ProtocolClientConfig {qSize
563566
send :: Transport c => ProtocolClient v err msg -> THandle v c 'TClient -> IO ()
564567
send ProtocolClient {client_ = PClient {sndQ}} h = forever $ atomically (readTBQueue sndQ) >>= sendPending
565568
where
566-
sendPending (Nothing, s) = send_ s
567-
sendPending (Just pending, s) = whenM (readTVarIO pending) $ send_ s
568-
send_ = void . tPutLog h
569+
sendPending (r, s) = case r of
570+
Nothing -> void $ tPutLog h s
571+
Just Request {pending, responseVar} ->
572+
whenM (readTVarIO pending) $ tPutLog h s >>= either responseErr pure
573+
where
574+
responseErr = atomically . putTMVar responseVar . Left . PCETransportError
569575

570576
receive :: Transport c => ProtocolClient v err msg -> THandle v c 'TClient -> IO ()
571577
receive ProtocolClient {client_ = PClient {rcvQ, lastReceived, timeoutErrorCount}} h = forever $ do
@@ -1101,12 +1107,12 @@ sendProtocolCommand_ c@ProtocolClient {client_ = PClient {sndQ}, thParams = THan
11011107
where
11021108
-- two separate "atomically" needed to avoid blocking
11031109
sendRecv :: Either TransportError SentRawTransmission -> Request err msg -> IO (Either (ProtocolClientError err) msg)
1104-
sendRecv t_ r@Request {pending} = case t_ of
1110+
sendRecv t_ r = case t_ of
11051111
Left e -> pure . Left $ PCETransportError e
11061112
Right t
11071113
| B.length s > blockSize - 2 -> pure . Left $ PCETransportError TELargeMsg
11081114
| otherwise -> do
1109-
atomically $ writeTBQueue sndQ (Just pending, s)
1115+
atomically $ writeTBQueue sndQ (Just r, s)
11101116
response <$> getResponse c tOut r
11111117
where
11121118
s

src/Simplex/Messaging/Notifications/Transport.hs

+2-2
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ ntfServerHandshake serverSignKey c (k, pk) kh ntfVRange = do
123123
Nothing -> throwE TEVersion
124124

125125
-- | Notifcations server client transport handshake.
126-
ntfClientHandshake :: forall c. Transport c => c -> C.KeyHash -> VersionRangeNTF -> ExceptT TransportError IO (THandleNTF c 'TClient)
127-
ntfClientHandshake c keyHash ntfVRange = do
126+
ntfClientHandshake :: forall c. Transport c => c -> C.KeyHash -> VersionRangeNTF -> Bool -> ExceptT TransportError IO (THandleNTF c 'TClient)
127+
ntfClientHandshake c keyHash ntfVRange _proxyServer = do
128128
let th@THandle {params = THandleParams {sessionId}} = ntfTHandle c
129129
NtfServerHandshake {sessionId = sessId, ntfVersionRange, authPubKey = sk'} <- getHandshake th
130130
if sessionId /= sessId

src/Simplex/Messaging/Protocol.hs

+5-9
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ supportedSMPClientVRange = mkVersionRange initialSMPClientVersion currentSMPClie
260260
-- TODO v6.0 remove dependency on version
261261
maxMessageLength :: VersionSMP -> Int
262262
maxMessageLength v
263-
| v >= encryptedBlockSMPVersion = 16048 -- max 16051
263+
| v >= encryptedBlockSMPVersion = 16048 -- max 16048
264264
| v >= sendingProxySMPVersion = 16064 -- max 16067
265265
| otherwise = 16088 -- 16048 - always use this size to determine allowed ranges
266266

@@ -1343,7 +1343,7 @@ transmissionP THandleParams {sessionId, implySessId} = do
13431343
class (ProtocolTypeI (ProtoType msg), ProtocolEncoding v err msg, ProtocolEncoding v err (ProtoCommand msg), Show err, Show msg) => Protocol v err msg | msg -> v, msg -> err where
13441344
type ProtoCommand msg = cmd | cmd -> msg
13451345
type ProtoType msg = (sch :: ProtocolType) | sch -> msg
1346-
protocolClientHandshake :: forall c. Transport c => c -> Maybe C.KeyPairX25519 -> C.KeyHash -> VersionRange v -> ExceptT TransportError IO (THandle v c 'TClient)
1346+
protocolClientHandshake :: forall c. Transport c => c -> Maybe C.KeyPairX25519 -> C.KeyHash -> VersionRange v -> Bool -> ExceptT TransportError IO (THandle v c 'TClient)
13471347
protocolPing :: ProtoCommand msg
13481348
protocolError :: msg -> Maybe err
13491349

@@ -1370,9 +1370,7 @@ instance PartyI p => ProtocolEncoding SMPVersion ErrorType (Command p) where
13701370
encodeProtocol v = \case
13711371
NEW rKey dhKey auth_ subMode sndSecure
13721372
| v >= sndAuthKeySMPVersion -> new <> e (auth_, subMode, sndSecure)
1373-
| v >= subModeSMPVersion -> new <> auth <> e subMode
1374-
| v == basicAuthSMPVersion -> new <> auth
1375-
| otherwise -> new
1373+
| otherwise -> new <> auth <> e subMode
13761374
where
13771375
new = e (NEW_, ' ', rKey, dhKey)
13781376
auth = maybe "" (e . ('A',)) auth_
@@ -1441,9 +1439,7 @@ instance ProtocolEncoding SMPVersion ErrorType Cmd where
14411439
Cmd SRecipient <$> case tag of
14421440
NEW_
14431441
| v >= sndAuthKeySMPVersion -> new <*> smpP <*> smpP <*> smpP
1444-
| v >= subModeSMPVersion -> new <*> auth <*> smpP <*> pure False
1445-
| v == basicAuthSMPVersion -> new <*> auth <*> pure SMSubscribe <*> pure False
1446-
| otherwise -> new <*> pure Nothing <*> pure SMSubscribe <*> pure False
1442+
| otherwise -> new <*> auth <*> smpP <*> pure False
14471443
where
14481444
new = NEW <$> _smpP <*> smpP
14491445
auth = optional (A.char 'A' *> smpP)
@@ -1495,7 +1491,7 @@ instance ProtocolEncoding SMPVersion ErrorType BrokerMsg where
14951491
INFO info -> e (INFO_, ' ', info)
14961492
OK -> e OK_
14971493
ERR err -> case err of
1498-
BLOCKED _ | v < blockedEntityErrorSMPVersion -> e (ERR_, ' ', AUTH)
1494+
BLOCKED _ | v < blockedEntitySMPVersion -> e (ERR_, ' ', AUTH)
14991495
_ -> e (ERR_, ' ', err)
15001496
PONG -> e PONG_
15011497
where

src/Simplex/Messaging/Server/Main.hs

+3-3
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,10 @@ import Simplex.Messaging.Server.Information
4747
import Simplex.Messaging.Server.MsgStore.Journal (JournalStoreConfig (..))
4848
import Simplex.Messaging.Server.MsgStore.Types (AMSType (..), SMSType (..), newMsgStore)
4949
import Simplex.Messaging.Server.QueueStore.STM (readQueueStore)
50-
import Simplex.Messaging.Transport (batchCmdsSMPVersion, currentServerSMPRelayVersion, simplexMQVersion, supportedServerSMPRelayVRange)
50+
import Simplex.Messaging.Transport (simplexMQVersion, supportedProxyClientSMPRelayVRange, supportedServerSMPRelayVRange)
5151
import Simplex.Messaging.Transport.Client (SocksProxy, TransportHost (..), defaultSocksProxy)
5252
import Simplex.Messaging.Transport.Server (ServerCredentials (..), TransportServerConfig (..), defaultTransportServerConfig)
5353
import Simplex.Messaging.Util (eitherToMaybe, ifM, safeDecodeUtf8, tshow)
54-
import Simplex.Messaging.Version (mkVersionRange)
5554
import System.Directory (createDirectoryIfMissing, doesDirectoryExist, doesFileExist)
5655
import System.Exit (exitFailure)
5756
import System.FilePath (combine)
@@ -447,8 +446,9 @@ smpServerCLI_ generateSite serveStaticFiles attachStaticFiles cfgPath logPath =
447446
defaultSMPClientAgentConfig
448447
{ smpCfg =
449448
(smpCfg defaultSMPClientAgentConfig)
450-
{ serverVRange = mkVersionRange batchCmdsSMPVersion currentServerSMPRelayVersion,
449+
{ serverVRange = supportedProxyClientSMPRelayVRange,
451450
agreeSecret = True,
451+
proxyServer = True,
452452
networkConfig =
453453
defaultNetworkConfig
454454
{ socksProxy = either error id <$!> strDecodeIni "PROXY" "socks_proxy" ini,

src/Simplex/Messaging/Server/Prometheus.hs

+2-2
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ prometheusMetrics sm rtm ts =
124124
\simplex_smp_queues_deleted{type=\"new\"} " <> mshow _qDeletedNew <> "\n# qDeletedNew\n\
125125
\simplex_smp_queues_deleted{type=\"secured\"} " <> mshow _qDeletedSecured <> "\n# qDeletedSecured\n\
126126
\\n\
127-
\# HELP simplex_smp_queues_deleted Deleted queues\n\
128-
\# TYPE simplex_smp_queues_deleted counter\n\
127+
\# HELP simplex_smp_queues_blocked Deleted queues\n\
128+
\# TYPE simplex_smp_queues_blocked counter\n\
129129
\simplex_smp_queues_blocked " <> mshow _qBlocked <> "\n# qBlocked\n\
130130
\\n\
131131
\# HELP simplex_smp_queues_deleted_batch Batched requests to delete queues\n\

0 commit comments

Comments
 (0)