Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 7 additions & 13 deletions go/extractor/registries/registryproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,13 @@ func getEnvVars() []string {
slog.Error("Failed to close the temporary certificate file", slog.String("error", err.Error()))
} else {
proxy_cert_file = f.Name()
result = append(result, fmt.Sprintf("SSL_CERT_FILE=%s", proxy_cert_file))
// `SSL_CERT_FILE` is used by Go itself; `GIT_SSL_CAINFO` is used by the `git`
// processes that `go` spawns to fetch `git_source` modules.
result = append(
result,
fmt.Sprintf("SSL_CERT_FILE=%s", proxy_cert_file),
fmt.Sprintf("GIT_SSL_CAINFO=%s", proxy_cert_file),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was already the case for SSL_CERT_FILE. So this seems out-of-scope of this PR?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ListWithEnv replaces the environment configured by GoCommand (go/extractor/toolchain/toolchain.go:226–227), and packages.Load receives no proxy environment (go/extractor/extractor.go:176–185).

These are existing (potential) issues unrelated to the change in this PR.

Removing the global http.sslCAInfo setting therefore leaves Git fetches from these paths without the proxy CA, so uncached private modules can fail certificate verification. Preserve the configured environment in ListWithEnv, pass it through packages.Config.Env, and add regression coverage for both paths.

This is logically disconnected from the previous part. If we don't configure the proxy for the above commands, then the certificate is also not needed. We either need everything at once or nothing.

I don't think we should address that some commands don't get the proxy environment in this PR. We haven't received any indications that this is a problem right now.


The behavioural change here is that we now always set GIT_SSL_CAINFO if the proxy is running, even if there are no git_source registries configured. Previously, we'd only run git config if there was at least one git_source.

This change makes sense though, because we previously also set the HTTP(S)_PROXY environment variables regardless of whether there was a git_source or not. The new behaviour for GIT_SSL_CAINFO makes sense with respect to that.

)
}
}

Expand Down Expand Up @@ -160,18 +166,6 @@ func getEnvVars() []string {

if len(git_sources) > 0 {
goprivate = append(goprivate, git_sources...)

if proxy_cert_file != "" {
slog.Info("Configuring `git` to use proxy certificate", slog.String("path", proxy_cert_file))
cmd := exec.Command("git", "config", "--global", "http.sslCAInfo", proxy_cert_file)

out, cmdErr := cmd.CombinedOutput()
slog.Info(string(out))

if cmdErr != nil {
slog.Error("Failed to configure `git` to accept the certificate file", slog.String("error", cmdErr.Error()))
}
}
}

result = append(result, fmt.Sprintf("GOPRIVATE=%s", strings.Join(goprivate, ",")))
Expand Down
22 changes: 22 additions & 0 deletions go/extractor/registries/registryproxy_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package registries

import (
"os"
"slices"
"testing"
)

Expand Down Expand Up @@ -131,3 +133,23 @@ func TestParseRegistryConfigsMultipleGoProxyServers(t *testing.T) {
t.Fatalf("Expected `URL` to be `https://goproxy.io`, but got `%s`", second.URL)
}
}

func TestGetEnvVarsScopesCertificateToSubprocesses(t *testing.T) {
t.Setenv(PROXY_HOST, "")
t.Setenv(PROXY_PORT, "")
t.Setenv(PROXY_URLS, "")
t.Setenv(PROXY_CA_CERTIFICATE, "dummy certificate")

vars := getEnvVars()
defer os.Remove(proxy_cert_file)

if proxy_cert_file == "" {
t.Fatal("Expected a temporary certificate file to be created.")
}

for _, expected := range []string{"SSL_CERT_FILE=" + proxy_cert_file, "GIT_SSL_CAINFO=" + proxy_cert_file} {
if !slices.Contains(vars, expected) {
t.Errorf("Expected `getEnvVars` to return %q, but got %v.", expected, vars)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: fix
---
* The Go extractor no longer modifies the global Git configuration when private `git_source` registries are configured. The registry proxy certificate is now passed to Git through the `GIT_SSL_CAINFO` environment variable instead, which only affects the Git processes spawned by `go`.
Loading