Billy Lynch uploaded a change:
https://go-review.googlesource.com/30135
cmd/go: Add support for GIT_ALLOW_PROTOCOL
Allows users to override the default secure protocol list by setting the
GIT_ALLOW_PROTOCOL environment variable.
Addresses #17299 for vcs.go.
Change-Id: If575861d2b1b04b59029fed7e5d12b49690af50a
---
M src/cmd/go/vcs.go
M src/cmd/go/vcs_test.go
2 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/src/cmd/go/vcs.go b/src/cmd/go/vcs.go
index 53ddbe6..9dae6db 100644
--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -41,7 +41,7 @@
resolveRepo func(v *vcsCmd, rootDir, remoteRepo string) (realRepo string,
err error)
}
-var isSecureScheme = map[string]bool{
+var defaultSecureScheme = map[string]bool{
"https": true,
"git+ssh": true,
"bzr+ssh": true,
@@ -55,7 +55,25 @@
// If repo is not a URL, it's not secure.
return false
}
- return isSecureScheme[u.Scheme]
+ return v.isSecureScheme(u.Scheme)
+}
+
+func (v *vcsCmd) isSecureScheme(scheme string) bool {
+ switch v.cmd {
+ case "git":
+ // GIT_ALLOW_PROTCOL is an environment variable defined by Git. It is a
+ // colon-separated list of schemes that are allowed to be used with git
+ // fetch/clone. Any scheme not mentioned will be considered insecure.
+ if allow := os.Getenv("GIT_ALLOW_PROTOCOL"); allow != "" {
+ for _, s := range strings.Split(allow, ":") {
+ if s == scheme {
+ return true
+ }
+ }
+ return false
+ }
+ }
+ return defaultSecureScheme[scheme]
}
// A tagCmd describes a command to list available tags
@@ -612,7 +630,7 @@
match["repo"] = scheme + "://" + match["repo"]
} else {
for _, scheme := range vcs.scheme {
- if security == secure && !isSecureScheme[scheme] {
+ if security == secure && !vcs.isSecureScheme(scheme) {
continue
}
if vcs.ping(scheme, match["repo"]) == nil {
diff --git a/src/cmd/go/vcs_test.go b/src/cmd/go/vcs_test.go
index 25e3866..e702fdb 100644
--- a/src/cmd/go/vcs_test.go
+++ b/src/cmd/go/vcs_test.go
@@ -229,6 +229,45 @@
}
}
+func TestIsSecureGitAllowProtocol(t *testing.T) {
+ tests := []struct {
+ vcs *vcsCmd
+ url string
+ secure bool
+ }{
+ // Same as TestIsSecure to verify same behavior.
+ {vcsGit, "
http://example.com/foo.git", false},
+ {vcsGit, "
https://example.com/foo.git", true},
+ {vcsBzr, "
http://example.com/foo.bzr", false},
+ {vcsBzr, "
https://example.com/foo.bzr", true},
+ {vcsSvn, "
http://example.com/svn", false},
+ {vcsSvn, "
https://example.com/svn", true},
+ {vcsHg, "
http://example.com/foo.hg", false},
+ {vcsHg, "
https://example.com/foo.hg", true},
+ {vcsGit, "user@server:path/to/repo.git", false},
+ {vcsGit, "user@server:", false},
+ {vcsGit, "server:repo.git", false},
+ {vcsGit, "server:path/to/repo.git", false},
+ {vcsGit, "example.com:path/to/repo.git", false},
+ {vcsGit, "path/that/contains/a:colon/repo.git", false},
+ {vcsHg, "ssh://
us...@example.com/path/to/repo.hg", true},
+ // New behavior.
+ {vcsGit, "ssh://
us...@example.com/foo.git", false},
+ {vcsGit, "foo://
example.com/bar.git", true},
+ {vcsHg, "foo://
example.com/bar.hg", false},
+ {vcsSvn, "foo://
example.com/svn", false},
+ {vcsBzr, "foo://
example.com/bar.bzr", false},
+ }
+
+ os.Setenv("GIT_ALLOW_PROTOCOL", "https:foo")
+ for _, test := range tests {
+ secure := test.vcs.isSecure(test.url)
+ if secure != test.secure {
+ t.Errorf("%s isSecure(%q) = %t; want %t", test.vcs, test.url, secure,
test.secure)
+ }
+ }
+}
+
func TestMatchGoImport(t *testing.T) {
tests := []struct {
imports []metaImport
--
https://go-review.googlesource.com/30135