p2phttp: Allow unauthenticated users to lock content by default
* p2phttp: Allow unauthenticated users to lock content by default. * p2phttp: Added --unauth-nolocking option to prevent unauthenticated users from locking content. The rationalle for this is that locking is not really a write operation, so makes sense to allow in a repository that only allows read-only access. Not supporting locking in that situation will prevent the user from dropping content from a special remote they control in cases where the other copy of the content is on the p2phttp server. Also, when p2phttp is configured to also allow authenticated access, lockcontent was resulting in a password prompt for users who had no way to authenticate. And there is no good way to distinguish between the two types of users client side. --unauth-nolocking anticipates that this might be abused, and seems better than disabling unauthenticated access entirely if a server is being attacked. It may be that rate limiting locking by IP address or similar would be an effective measure in such a situation. Or just limiting the number of locks by anonymous users that can be live at any one time. Since the impact of such an DOS attempt is limited to preventing dropping content from the server, it seems not a very appealing target anyway.
This commit is contained in:
parent
87c88025d1
commit
de138c642b
7 changed files with 60 additions and 10 deletions
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 }, _) ->
|
||||
|
|
|
@ -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]]
|
||||
|
|
|
@ -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.
|
||||
"""]]
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue