diff --git a/debian/changelog b/debian/changelog index ce1489e9d0..4e0a1e21e4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,9 @@ git-annex (3.20111012) UNRELEASED; urgency=low * A remote can have a annexUrl configured, that is used by git-annex instead of its usual url. (Similar to pushUrl.) * migrate: Copy url logs for keys when migrating. + * git-annex-shell: GIT_ANNEX_SHELL_READONLY and GIT_ANNEX_SHELL_LIMITED + environment variables can be set to limit what commands can be run. + This could be used by eg, gitolite. -- Joey Hess Fri, 14 Oct 2011 18:15:20 -0400 diff --git a/doc/git-annex-shell.mdwn b/doc/git-annex-shell.mdwn index 1fc9647c88..fc5bc6c2d6 100644 --- a/doc/git-annex-shell.mdwn +++ b/doc/git-annex-shell.mdwn @@ -19,6 +19,10 @@ user's restricted login shell. Any command not listed below is passed through to git-shell. +Note that the directory parameter should be an absolute path, otherwise +it is assumed to be relative to the user's home directory. Also the +first "/~/" or "/~user/" is expanded to the specified home directory. + * configlist directory This outputs a subset of the git configuration, in the same form as @@ -44,11 +48,23 @@ Any command not listed below is passed through to git-shell. # OPTIONS -Same as git-annex or git-shell, depending on the command being run. +Most options are the same as in git-annex. The ones specific +to git-annex-shell are: -Note that the directory parameter should be an absolute path, otherwise -it is assumed to be relative to the user's home directory. Also the -first "/~/" or "/~user/" is expanded to the specified home directory. +* --uuid=UUID + + git-annex uses this to specify the UUID of the repository it was expecting + git-annex-shell to access, as a sanity check. + +# ENVIRONMENT + +* GIT_ANNEX_SHELL_READONLY + + If set, disallows any command that could modify the repository. + +* GIT_ANNEX_SHELL_LIMITED + + If set, disallows running git-shell to handle unknown commands. # SEE ALSO diff --git a/git-annex-shell.hs b/git-annex-shell.hs index 72e130ff08..41cb72d7e2 100644 --- a/git-annex-shell.hs +++ b/git-annex-shell.hs @@ -21,21 +21,29 @@ import qualified Command.DropKey import qualified Command.RecvKey import qualified Command.SendKey -cmds :: [Command] -cmds = map adddirparam $ concat +cmds_readonly :: [Command] +cmds_readonly = concat [ Command.ConfigList.command , Command.InAnnex.command - , Command.DropKey.command - , Command.RecvKey.command , Command.SendKey.command ] + +cmds_notreadonly :: [Command] +cmds_notreadonly = concat + [ Command.RecvKey.command + , Command.DropKey.command + ] + +cmds :: [Command] +cmds = map adddirparam $ cmds_readonly ++ cmds_notreadonly where adddirparam c = c { cmdparams = "DIRECTORY " ++ cmdparams c } options :: [OptDescr (Annex ())] -options = uuid : commonOptions +options = commonOptions ++ + [ Option [] ["uuid"] (ReqArg check paramUUID) "repository uuid" + ] where - uuid = Option [] ["uuid"] (ReqArg check paramUUID) "repository uuid" check expected = do u <- getUUID when (u /= expected) $ error $ @@ -67,12 +75,14 @@ builtins :: [String] builtins = map cmdname cmds builtin :: String -> String -> [String] -> IO () -builtin cmd dir params = +builtin cmd dir params = do + checkNotReadOnly cmd Git.repoAbsPath dir >>= Git.repoFromAbsPath >>= dispatch (cmd : filterparams params) cmds options header external :: [String] -> IO () -external params = +external params = do + checkNotLimited unlessM (boolSystem "git-shell" $ map Param $ "-c":filterparams params) $ error "git-shell failed" @@ -85,3 +95,19 @@ filterparams (a:as) = a:filterparams as failure :: IO () failure = error $ "bad parameters\n\n" ++ usage header cmds options + +checkNotLimited :: IO () +checkNotLimited = checkEnv "GIT_ANNEX_SHELL_LIMITED" + +checkNotReadOnly :: String -> IO () +checkNotReadOnly cmd + | cmd `elem` map cmdname cmds_readonly = return () + | otherwise = checkEnv "GIT_ANNEX_SHELL_READONLY" + +checkEnv :: String -> IO () +checkEnv var = catch check (const $ return ()) + where + check = do + val <- getEnv var + when (not $ null val) $ + error $ "Action blocked by " ++ var