From 46bc33819ac86a9596b8059235842f0e0c7469bd Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Thu, 2 Nov 2023 15:06:35 -0400 Subject: [PATCH] [release-branch.go1.20] cmd/go/internal/vcs: error out if the requested repo does not support a secure protocol Updates #63845. Fixes #63972. Change-Id: If86d6b13d3b55877b35c087112bd76388c9404b8 Reviewed-on: https://go-review.googlesource.com/c/go/+/539321 Reviewed-by: Michael Matloob LUCI-TryBot-Result: Go LUCI Reviewed-by: Roland Shoemaker Auto-Submit: Bryan Mills (cherry picked from commit be26ae18caf7ddffca4073333f80d0d9e76483c3) Reviewed-on: https://go-review.googlesource.com/c/go/+/540335 Auto-Submit: Dmitri Shuralyov Reviewed-by: Dmitri Shuralyov --- src/cmd/go/internal/vcs/vcs.go | 25 +++++++++++++---- .../script/mod_insecure_issue63845.txt | 28 +++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 src/cmd/go/testdata/script/mod_insecure_issue63845.txt diff --git a/src/cmd/go/internal/vcs/vcs.go b/src/cmd/go/internal/vcs/vcs.go index 12ea0524826d8..695bb4b616da0 100644 --- a/src/cmd/go/internal/vcs/vcs.go +++ b/src/cmd/go/internal/vcs/vcs.go @@ -1179,18 +1179,31 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths var ok bool repoURL, ok = interceptVCSTest(repo, vcs, security) if !ok { - scheme := vcs.Scheme[0] // default to first scheme - if vcs.PingCmd != "" { - // If we know how to test schemes, scan to find one. + scheme, err := func() (string, error) { for _, s := range vcs.Scheme { if security == web.SecureOnly && !vcs.isSecureScheme(s) { continue } - if vcs.Ping(s, repo) == nil { - scheme = s - break + + // If we know how to ping URL schemes for this VCS, + // check that this repo works. + // Otherwise, default to the first scheme + // that meets the requested security level. + if vcs.PingCmd == "" { + return s, nil + } + if err := vcs.Ping(s, repo); err == nil { + return s, nil } } + securityFrag := "" + if security == web.SecureOnly { + securityFrag = "secure " + } + return "", fmt.Errorf("no %sprotocol found for repository", securityFrag) + }() + if err != nil { + return nil, err } repoURL = scheme + "://" + repo } diff --git a/src/cmd/go/testdata/script/mod_insecure_issue63845.txt b/src/cmd/go/testdata/script/mod_insecure_issue63845.txt new file mode 100644 index 0000000000000..5fa6a4f12b81b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_insecure_issue63845.txt @@ -0,0 +1,28 @@ +# Regression test for https://go.dev/issue/63845: +# If 'git ls-remote' fails for all secure protocols, +# we should fail instead of falling back to an arbitrary protocol. +# +# Note that this test does not use the local vcweb test server +# (vcs-test.golang.org), because the hook for redirecting to that +# server bypasses the "ping to determine protocol" logic +# in cmd/go/internal/vcs. + +[!net] skip +[!git] skip +[short] skip 'tries to access a nonexistent external Git repo' + +env GOPRIVATE=golang.org +env CURLOPT_TIMEOUT_MS=100 +env GIT_SSH_COMMAND=false + +! go get -x golang.org/nonexist.git@latest +stderr '^git ls-remote https://golang.org/nonexist$' +stderr '^git ls-remote git\+ssh://golang.org/nonexist' +stderr '^git ls-remote ssh://golang.org/nonexist$' +! stderr 'git://' +stderr '^go: golang.org/nonexist.git@latest: no secure protocol found for repository$' + +-- go.mod -- +module example + +go 1.19