From 0dfdc9f951b54bc14d90ef0db9ec9b92c86246fa Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 1 Jul 2024 10:04:45 -0400 Subject: [PATCH] dup stdio handles for P2P proxy Special remotes might output to stdout, or read from stdin, which would mess up the P2P protocol. So dup the handles to avoid any such problem. --- Command/P2PStdIO.hs | 2 +- P2P/IO.hs | 17 ++++++++++++++++- doc/todo/git-annex_proxies.mdwn | 7 ------- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Command/P2PStdIO.hs b/Command/P2PStdIO.hs index 4b38057e58..910d9cb7cc 100644 --- a/Command/P2PStdIO.hs +++ b/Command/P2PStdIO.hs @@ -99,7 +99,7 @@ performProxyCluster clientuuid clusteruuid servermode = do proxyClientSide :: UUID -> Annex ClientSide proxyClientSide clientuuid = do clientrunst <- liftIO (mkRunState $ Serving clientuuid Nothing) - return $ ClientSide clientrunst (stdioP2PConnection Nothing) + ClientSide clientrunst <$> liftIO (stdioP2PConnectionDupped Nothing) p2pErrHandler :: Annex () -> (a -> CommandPerform) -> Annex (Either ProtoFailure a) -> CommandPerform p2pErrHandler closeconn cont a = a >>= \case diff --git a/P2P/IO.hs b/P2P/IO.hs index 15e0dccde4..42b53a671a 100644 --- a/P2P/IO.hs +++ b/P2P/IO.hs @@ -1,6 +1,6 @@ {- P2P protocol, IO implementation - - - Copyright 2016-2018 Joey Hess + - Copyright 2016-2024 Joey Hess - - Licensed under the GNU AGPL version 3 or higher. -} @@ -16,6 +16,7 @@ module P2P.IO , ConnIdent(..) , ClosableConnection(..) , stdioP2PConnection + , stdioP2PConnectionDupped , connectPeer , closeConnection , serveUnixSocket @@ -104,6 +105,20 @@ stdioP2PConnection g = P2PConnection , connIdent = ConnIdent Nothing } +-- P2PConnection using stdio, but with the handles first duplicated, +-- to avoid anything that might output to stdio (eg a program run by a +-- special remote) from interfering with the connection. +stdioP2PConnectionDupped :: Maybe Git.Repo -> IO P2PConnection +stdioP2PConnectionDupped g = do + (readh, writeh) <- dupIoHandles + return $ P2PConnection + { connRepo = g + , connCheckAuth = const False + , connIhdl = P2PHandle readh + , connOhdl = P2PHandle writeh + , connIdent = ConnIdent Nothing + } + -- Opens a connection to a peer. Does not authenticate with it. connectPeer :: Maybe Git.Repo -> P2PAddress -> IO P2PConnection connectPeer g (TorAnnex onionaddress onionport) = do diff --git a/doc/todo/git-annex_proxies.mdwn b/doc/todo/git-annex_proxies.mdwn index 50eb5aeef3..8d803ec893 100644 --- a/doc/todo/git-annex_proxies.mdwn +++ b/doc/todo/git-annex_proxies.mdwn @@ -45,13 +45,6 @@ For June's work on [[design/passthrough_proxy]], remaining todos: rather than PUT-FROM or ALREADY-HAVE. Verify that the client processes that ok and displays it to the user. -* If a special remote outputs to stdout, or reads from stdin, that will - mess up the P2P protocol. Move the special remote proxying into a - separate process perhaps, which can be run with stdout and stdin - redirected? Or, fix any special remotes that might do that. Are - there any left? External special remotes certainly don't since that would - mess up their own protocol. Hook special remotes can though. - * Streaming download from proxied special remotes. See design. * Check annex.diskreserve when proxying for special remotes.