87 lines
3.5 KiB
Diff
87 lines
3.5 KiB
Diff
40a41
|
|
> gitAnnexShellVerb = "git-annex-shell"
|
|
81a83
|
|
> gitAnnexShellVerb: perm.AccessModeNone, // annex permissions are enforced by GIT_ANNEX_SHELL_READONLY, rather than the Gitea API
|
|
214a217,238
|
|
> if verb == gitAnnexShellVerb {
|
|
> if !setting.Annex.Enabled {
|
|
> return fail(ctx, "Unknown git command", "git-annex request over SSH denied, git-annex support is disabled")
|
|
> }
|
|
>
|
|
> if len(words) < 3 {
|
|
> return fail(ctx, "Too few arguments", "Too few arguments in cmd: %s", cmd)
|
|
> }
|
|
>
|
|
> // git-annex always puts the repo in words[2], unlike most other
|
|
> // git subcommands; and it sometimes names repos like /~/, as if
|
|
> // $HOME should get expanded while also being rooted. e.g.:
|
|
> // git-annex-shell 'configlist' '/~/user/repo'
|
|
> // git-annex-shell 'sendkey' '/user/repo 'key'
|
|
> repoPath = words[2]
|
|
> repoPath = strings.TrimPrefix(repoPath, "/")
|
|
> repoPath = strings.TrimPrefix(repoPath, "~/")
|
|
> }
|
|
>
|
|
> // prevent directory traversal attacks
|
|
> repoPath = filepath.Clean("/" + repoPath)[1:]
|
|
>
|
|
227a252,263
|
|
> // put the sanitized repoPath back into the argument list for later
|
|
> if verb == gitAnnexShellVerb {
|
|
> // git-annex-shell demands an absolute path
|
|
> absRepoPath, err := filepath.Abs(filepath.Join(setting.RepoRootPath, repoPath))
|
|
> if err != nil {
|
|
> return fail(ctx, "Error locating repoPath", "%v", err)
|
|
> }
|
|
> words[2] = absRepoPath
|
|
> } else {
|
|
> words[1] = repoPath
|
|
> }
|
|
>
|
|
306,309c342,343
|
|
< var gitcmd *exec.Cmd
|
|
< gitBinPath := filepath.Dir(git.GitExecutable) // e.g. /usr/bin
|
|
< gitBinVerb := filepath.Join(gitBinPath, verb) // e.g. /usr/bin/git-upload-pack
|
|
< if _, err := os.Stat(gitBinVerb); err != nil {
|
|
---
|
|
> gitBinVerb, err := exec.LookPath(verb)
|
|
> if err != nil {
|
|
311a346,347
|
|
> // ps: git-annex-shell and other extensions may not necessarily be in gitBinPath,
|
|
> // but '{gitBinPath}/git annex-shell' should be able to find them on $PATH.
|
|
315c351,352
|
|
< gitcmd = exec.CommandContext(ctx, git.GitExecutable, verbFields[1], repoPath)
|
|
---
|
|
> gitBinVerb = git.GitExecutable
|
|
> words = append([]string{verbFields[1]}, words...)
|
|
318,320c355,380
|
|
< if gitcmd == nil {
|
|
< // by default, use the verb (it has been checked above by allowedCommands)
|
|
< gitcmd = exec.CommandContext(ctx, gitBinVerb, repoPath)
|
|
---
|
|
>
|
|
> // by default, use the verb (it has been checked above by allowedCommands)
|
|
> gitcmd := exec.CommandContext(ctx, gitBinVerb, words[1:]...)
|
|
>
|
|
> if verb == gitAnnexShellVerb {
|
|
> // This doesn't get its own isolated section like LFS does, because LFS
|
|
> // is handled by internal Gitea routines, but git-annex has to be shelled out
|
|
> // to like other git subcommands, so we need to build up gitcmd.
|
|
>
|
|
> // TODO: does this work on Windows?
|
|
> gitcmd.Env = append(gitcmd.Env,
|
|
> // "If set, disallows running git-shell to handle unknown commands."
|
|
> // - git-annex-shell(1)
|
|
> "GIT_ANNEX_SHELL_LIMITED=True",
|
|
> // "If set, git-annex-shell will refuse to run commands
|
|
> // that do not operate on the specified directory."
|
|
> // - git-annex-shell(1)
|
|
> fmt.Sprintf("GIT_ANNEX_SHELL_DIRECTORY=%s", words[2]),
|
|
> )
|
|
> if results.UserMode < perm.AccessModeWrite {
|
|
> // "If set, disallows any action that could modify the git-annex repository."
|
|
> // - git-annex-shell(1)
|
|
> // We set this when the backend API has told us that we don't have write permission to this repo.
|
|
> log.Debug("Setting GIT_ANNEX_SHELL_READONLY=True")
|
|
> gitcmd.Env = append(gitcmd.Env, "GIT_ANNEX_SHELL_READONLY=True")
|
|
> }
|