From 0222623be9fa4a56d870213f77b92139cefc2518 Mon Sep 17 00:00:00 2001 From: Michael Kuhn Date: Wed, 28 Nov 2018 08:00:25 +0100 Subject: [PATCH] Explicitly disable Git credential helper (#5367) * Explicitly disable Git credential helper If the user running Gitea has configured a credential helper, Git credentials might leak out of Gitea. There are two problems with credential helpers when combined with Gitea: 1. Credentials entered by a user when doing a migration or setting up a mirror will end up in the credential store. In the worst case, this is the plain text file ~/.git-credentials. 2. Credentials in the credential store will be used for migrations and mirrors by all users. For example, if user A sets up a mirror, their credentials will be stored. If user B later sets up a mirror from the same host and does not enter any credentials, user A's credentials will be used. This PR prepends -c credential.helper= to all Git commands to clear the list of helpers. This requires at least Git version 2.9, as previous versions will try to load an empty helper instead. For more details, see https://github.com/git/git/commit/24321375cda79f141be72d1a842e930df6f41725 * Update git module --- Gopkg.lock | 4 ++-- modules/setting/setting.go | 29 +++++++++++--------------- vendor/code.gitea.io/git/command.go | 5 ++++- vendor/code.gitea.io/git/repo_tree.go | 9 ++++++++ vendor/code.gitea.io/git/tree.go | 14 +++++++++++++ vendor/code.gitea.io/git/tree_entry.go | 15 ++++++++----- 6 files changed, 51 insertions(+), 25 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 5142aa40d..670f11887 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -3,11 +3,11 @@ [[projects]] branch = "master" - digest = "1:ebd587087cf937b6d3db7dde843a557d157fd68820a9d3d0157a8d8f4011ad29" + digest = "1:ab875622908a804a327a95a1701002b150806a3c5406df51ec231eac16d3a1ca" name = "code.gitea.io/git" packages = ["."] pruneopts = "NUT" - revision = "578ad8f1259b0d660d19b05a011596f8fd3fea37" + revision = "389d3c803e12a30dffcbb54a15c2242521bc4333" [[projects]] branch = "master" diff --git a/modules/setting/setting.go b/modules/setting/setting.go index ea0fa73dd..f7da6baac 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -34,6 +34,7 @@ import ( _ "github.com/go-macaron/session/redis" // redis plugin for store session "github.com/go-xorm/core" "github.com/kballard/go-shellquote" + "github.com/mcuadros/go-version" "gopkg.in/ini.v1" "strk.kbt.io/projects/go/libravatar" ) @@ -929,23 +930,7 @@ func NewContext() { log.Fatal(4, "Error retrieving git version: %v", err) } - splitVersion := strings.SplitN(binVersion, ".", 4) - - majorVersion, err := strconv.ParseUint(splitVersion[0], 10, 64) - if err != nil { - log.Fatal(4, "Error parsing git major version: %v", err) - } - minorVersion, err := strconv.ParseUint(splitVersion[1], 10, 64) - if err != nil { - log.Fatal(4, "Error parsing git minor version: %v", err) - } - revisionVersion, err := strconv.ParseUint(splitVersion[2], 10, 64) - if err != nil { - log.Fatal(4, "Error parsing git revision version: %v", err) - } - - if !((majorVersion > 2) || (majorVersion == 2 && minorVersion > 1) || - (majorVersion == 2 && minorVersion == 1 && revisionVersion >= 2)) { + if !version.Compare(binVersion, "2.1.2", ">=") { LFS.StartServer = false log.Error(4, "LFS server support needs at least Git v2.1.2") @@ -1206,6 +1191,16 @@ func NewContext() { sec = Cfg.Section("U2F") U2F.TrustedFacets, _ = shellquote.Split(sec.Key("TRUSTED_FACETS").MustString(strings.TrimRight(AppURL, "/"))) U2F.AppID = sec.Key("APP_ID").MustString(strings.TrimRight(AppURL, "/")) + + binVersion, err := git.BinVersion() + if err != nil { + log.Fatal(4, "Error retrieving git version: %v", err) + } + + if version.Compare(binVersion, "2.9", ">=") { + // Explicitly disable credential helper, otherwise Git credentials might leak + git.GlobalCommandArgs = append(git.GlobalCommandArgs, "-c", "credential.helper=") + } } // Service settings diff --git a/vendor/code.gitea.io/git/command.go b/vendor/code.gitea.io/git/command.go index 8ca99fd6d..fc48d2871 100644 --- a/vendor/code.gitea.io/git/command.go +++ b/vendor/code.gitea.io/git/command.go @@ -37,9 +37,12 @@ func (c *Command) String() string { // NewCommand creates and returns a new Git Command based on given command and arguments. func NewCommand(args ...string) *Command { + // Make an explicit copy of GlobalCommandArgs, otherwise append might overwrite it + cargs := make([]string, len(GlobalCommandArgs)) + copy(cargs, GlobalCommandArgs) return &Command{ name: "git", - args: append(GlobalCommandArgs, args...), + args: append(cargs, args...), } } diff --git a/vendor/code.gitea.io/git/repo_tree.go b/vendor/code.gitea.io/git/repo_tree.go index 6e3843f7e..146b919d7 100644 --- a/vendor/code.gitea.io/git/repo_tree.go +++ b/vendor/code.gitea.io/git/repo_tree.go @@ -18,6 +18,15 @@ func (repo *Repository) getTree(id SHA1) (*Tree, error) { // GetTree find the tree object in the repository. func (repo *Repository) GetTree(idStr string) (*Tree, error) { + if len(idStr) != 40 { + res, err := NewCommand("rev-parse", idStr).RunInDir(repo.Path) + if err != nil { + return nil, err; + } + if len(res) > 0 { + idStr = res[:len(res)-1] + } + } id, err := NewIDFromString(idStr) if err != nil { return nil, err diff --git a/vendor/code.gitea.io/git/tree.go b/vendor/code.gitea.io/git/tree.go index 4654dac30..b67bf5584 100644 --- a/vendor/code.gitea.io/git/tree.go +++ b/vendor/code.gitea.io/git/tree.go @@ -70,3 +70,17 @@ func (t *Tree) ListEntries() (Entries, error) { t.entries, err = parseTreeEntries(stdout, t) return t.entries, err } + +// ListEntriesRecursive returns all entries of current tree recursively including all subtrees +func (t *Tree) ListEntriesRecursive() (Entries, error) { + if t.entriesParsed { + return t.entries, nil + } + stdout, err := NewCommand("ls-tree", "-t", "-r", t.ID.String()).RunInDirBytes(t.repo.Path) + + if err != nil { + return nil, err + } + t.entries, err = parseTreeEntries(stdout, t) + return t.entries, err +} diff --git a/vendor/code.gitea.io/git/tree_entry.go b/vendor/code.gitea.io/git/tree_entry.go index 6201eef8f..ead0d4f5d 100644 --- a/vendor/code.gitea.io/git/tree_entry.go +++ b/vendor/code.gitea.io/git/tree_entry.go @@ -18,15 +18,15 @@ type EntryMode int // one of these. const ( // EntryModeBlob - EntryModeBlob EntryMode = 0100644 + EntryModeBlob EntryMode = 0x0100644 // EntryModeExec - EntryModeExec EntryMode = 0100755 + EntryModeExec EntryMode = 0x0100755 // EntryModeSymlink - EntryModeSymlink EntryMode = 0120000 + EntryModeSymlink EntryMode = 0x0120000 // EntryModeCommit - EntryModeCommit EntryMode = 0160000 + EntryModeCommit EntryMode = 0x0160000 // EntryModeTree - EntryModeTree EntryMode = 0040000 + EntryModeTree EntryMode = 0x0040000 ) // TreeEntry the leaf in the git tree @@ -50,6 +50,11 @@ func (te *TreeEntry) Name() string { return te.name } +// Mode returns the mode of the entry +func (te *TreeEntry) Mode() EntryMode { + return te.mode +} + // Size returns the size of the entry func (te *TreeEntry) Size() int64 { if te.IsDir() {