diff --git a/CHANGELOG b/CHANGELOG index 7bcb3560a4..dc4598362c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,9 @@ git-annex (10.20240928) UNRELEASED; urgency=medium * p2phttp: Support serving unauthenticated users while requesting authentication for operations that need it. Eg, --unauth-readonly can be combined with --authenv. + * p2phttp: Allow unauthenticated users to lock content by default. + * p2phttp: Added --unauth-nolocking option to prevent unauthenticated + users from locking content. * Allow enabling the servant build flag with older versions of stm, allowing building with ghc 9.0.2. * git-remote-annex: Fix bug that prevented using it with external special diff --git a/Command/P2PHttp.hs b/Command/P2PHttp.hs index a377dd6e0a..e4ebfc3bec 100644 --- a/Command/P2PHttp.hs +++ b/Command/P2PHttp.hs @@ -40,6 +40,7 @@ data Options = Options , authEnvHttpOption :: Bool , unauthReadOnlyOption :: Bool , unauthAppendOnlyOption :: Bool + , unauthNoLockingOption :: Bool , wideOpenOption :: Bool , proxyConnectionsOption :: Maybe Integer , clusterJobsOption :: Maybe Int @@ -83,6 +84,10 @@ optParser _ = Options ( long "unauth-appendonly" <> help "allow unauthenticated users to read and append to the repository" ) + <*> switch + ( long "unauth-nolocking" + <> help "prevent unauthenticated users from locking content in the repository" + ) <*> switch ( long "wideopen" <> help "give unauthenticated users full read+write access" @@ -128,15 +133,25 @@ seek o = getAnnexWorkerPool $ \workerpool -> mkGetServerMode :: M.Map Auth P2P.ServerMode -> Options -> GetServerMode mkGetServerMode _ o _ Nothing - | wideOpenOption o = - ServerMode P2P.ServeReadWrite False - | unauthAppendOnlyOption o = - ServerMode P2P.ServeAppendOnly canauth - | unauthReadOnlyOption o = - ServerMode P2P.ServeReadOnly canauth + | wideOpenOption o = ServerMode + { serverMode = P2P.ServeReadWrite + , unauthenticatedLockingAllowed = unauthlock + , authenticationAllowed = False + } + | unauthAppendOnlyOption o = ServerMode + { serverMode = P2P.ServeAppendOnly + , unauthenticatedLockingAllowed = unauthlock + , authenticationAllowed = canauth + } + | unauthReadOnlyOption o = ServerMode + { serverMode = P2P.ServeReadOnly + , unauthenticatedLockingAllowed = unauthlock + , authenticationAllowed = canauth + } | otherwise = CannotServeRequests where canauth = authEnvOption o || authEnvHttpOption o + unauthlock = not (unauthNoLockingOption o) mkGetServerMode authenv o issecure (Just auth) = case (issecure, authEnvOption o, authEnvHttpOption o) of (Secure, True, _) -> checkauth @@ -144,7 +159,11 @@ mkGetServerMode authenv o issecure (Just auth) = _ -> noauth where checkauth = case M.lookup auth authenv of - Just servermode -> ServerMode servermode False + Just servermode -> ServerMode + { serverMode = servermode + , authenticationAllowed = False + , unauthenticatedLockingAllowed = False + } Nothing -> noauth noauth = mkGetServerMode authenv noautho issecure Nothing noautho = o { authEnvOption = False, authEnvHttpOption = False } diff --git a/P2P/Http/Server.hs b/P2P/Http/Server.hs index f3f5a46219..124994197f 100644 --- a/P2P/Http/Server.hs +++ b/P2P/Http/Server.hs @@ -425,7 +425,7 @@ serveLockContent -> Maybe Auth -> Handler LockResult serveLockContent st su apiver (B64Key k) cu bypass sec auth = do - conn <- getP2PConnection apiver st cu su bypass sec auth WriteAction id + conn <- getP2PConnection apiver st cu su bypass sec auth LockAction id let lock = do lockresv <- newEmptyTMVarIO unlockv <- newEmptyTMVarIO @@ -465,7 +465,7 @@ serveKeepLocked -> S.SourceT IO UnlockRequest -> Handler LockResult serveKeepLocked st _su _apiver lckid _cu _bypass sec auth _ _ unlockrequeststream = do - checkAuthActionClass st sec auth WriteAction $ \_ -> do + checkAuthActionClass st sec auth LockAction $ \_ -> do liftIO $ keepingLocked lckid st _ <- liftIO $ S.unSourceT unlockrequeststream go return (LockResult False Nothing) diff --git a/P2P/Http/State.hs b/P2P/Http/State.hs index fdaaf44962..302880b931 100644 --- a/P2P/Http/State.hs +++ b/P2P/Http/State.hs @@ -57,6 +57,7 @@ type GetServerMode = IsSecure -> Maybe Auth -> ServerMode data ServerMode = ServerMode { serverMode :: P2P.ServerMode + , unauthenticatedLockingAllowed :: Bool , authenticationAllowed :: Bool } | CannotServeRequests @@ -68,7 +69,7 @@ mkP2PHttpServerState acquireconn annexworkerpool getservermode = P2PHttpServerSt <*> pure getservermode <*> newTMVarIO mempty -data ActionClass = ReadAction | WriteAction | RemoveAction +data ActionClass = ReadAction | WriteAction | RemoveAction | LockAction deriving (Eq) withP2PConnection @@ -152,6 +153,8 @@ checkAuthActionClass st sec auth actionclass go = case (sm, actionclass) of (ServerMode { serverMode = P2P.ServeReadWrite }, _) -> go P2P.ServeReadWrite + (ServerMode { unauthenticatedLockingAllowed = True }, LockAction) -> + go P2P.ServeReadOnly (ServerMode { serverMode = P2P.ServeAppendOnly }, RemoveAction) -> throwError $ forbiddenWithoutAuth sm (ServerMode { serverMode = P2P.ServeAppendOnly }, _) -> diff --git a/doc/bugs/p2phttp__58___drop_difference_wideopen_unauth-readonly.mdwn b/doc/bugs/p2phttp__58___drop_difference_wideopen_unauth-readonly.mdwn index 731a0f1df0..d64cb946a9 100644 --- a/doc/bugs/p2phttp__58___drop_difference_wideopen_unauth-readonly.mdwn +++ b/doc/bugs/p2phttp__58___drop_difference_wideopen_unauth-readonly.mdwn @@ -41,3 +41,5 @@ local repository version: 10 ### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders) [[!tag projects/INM7]] + +> [[fixed|done]] --[[Joey]] diff --git a/doc/bugs/p2phttp__58___drop_difference_wideopen_unauth-readonly/comment_10_34c0c0e2bcd28f95a5aef47652c0f18e._comment b/doc/bugs/p2phttp__58___drop_difference_wideopen_unauth-readonly/comment_10_34c0c0e2bcd28f95a5aef47652c0f18e._comment new file mode 100644 index 0000000000..73a76cbd2d --- /dev/null +++ b/doc/bugs/p2phttp__58___drop_difference_wideopen_unauth-readonly/comment_10_34c0c0e2bcd28f95a5aef47652c0f18e._comment @@ -0,0 +1,10 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 10""" + date="2024-10-21T13:46:00Z" + content=""" +Ok I decided to allow locking for unauthenticated users by default. + +In case that gets abused there is a --unauth-nolocking option which will +result in a 401 when --authenv is used, or a 403 otherwise. +"""]] diff --git a/doc/git-annex-p2phttp.mdwn b/doc/git-annex-p2phttp.mdwn index 8d9b1a6fa6..802c52d929 100644 --- a/doc/git-annex-p2phttp.mdwn +++ b/doc/git-annex-p2phttp.mdwn @@ -127,6 +127,19 @@ convenient way to download the content of any key, by using the path This can be combined with `--authenv` or `--authenv-http` to allow anonymous appendonly access, and authenticated remove access. +* `--unauth-nolocking` + + By default, when `--unauth-readonly` or `--unauth-appendonly` is used, + unauthenticated users are allowed to lock content in the repository. + This option prevents that. + + Locking content prevents it from being dropped from the repository + so it may be that an unauthenticated user abuses that, and this option + can be used in such a situation. + + Note that enabling this option will prevent unauthenticated users from + dropping content from their other remotes in some cases. + * `--wideopen` Gives unauthenticated users full read+write+remove access to the