From 320c4d37196804e92f2ebf80a5583cb322b36d98 Mon Sep 17 00:00:00 2001 From: Guillaume Rose Date: Thu, 24 Jun 2021 14:14:39 +0200 Subject: [PATCH] Add proxy-ca-file to http transport Segment and version check may use the proxy via HTTP_PROXY env variables. This doesn't include the proxy CA. This change loads the cert from proxy-ca-file configuration key and use it when it is possible. How to test: * run mitmproxy * crc config set proxy-ca-file $HOME/.mitmproxy/mitmproxy-ca-cert.cer * run crc version with telemetry enabled. --- cmd/crc/cmd/root.go | 25 ++++++++++++++++++++++++- cmd/crc/cmd/start.go | 2 +- pkg/crc/segment/segment.go | 8 +++++--- pkg/crc/segment/segment_test.go | 8 ++++---- pkg/crc/version/version.go | 5 +++-- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/cmd/crc/cmd/root.go b/cmd/crc/cmd/root.go index 144723b036..063b903ef4 100644 --- a/cmd/crc/cmd/root.go +++ b/cmd/crc/cmd/root.go @@ -2,9 +2,12 @@ package cmd import ( "context" + "crypto/tls" + "crypto/x509" "errors" "fmt" "io/ioutil" + "net/http" "os" "strings" "time" @@ -56,7 +59,7 @@ func init() { logging.Fatal(err.Error()) } // Initiate segment client - if segmentClient, err = segment.NewClient(config); err != nil { + if segmentClient, err = segment.NewClient(config, httpTransport()); err != nil { logging.Fatal(err.Error()) } @@ -207,3 +210,23 @@ func attachMiddleware(names []string, cmd *cobra.Command) { cmd.RunE = executeWithLogging(fullCmd, src) } } + +func httpTransport() http.RoundTripper { + if config.Get(crcConfig.ProxyCAFile).IsDefault { + return http.DefaultTransport + } + caCert, err := ioutil.ReadFile(config.Get(crcConfig.ProxyCAFile).AsString()) + if err != nil { + logging.Errorf("Cannot read proxy-ca-file, using default http transport: %v", err) + return http.DefaultTransport + } + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + TLSClientConfig: &tls.Config{ + MinVersion: tls.VersionTLS12, + RootCAs: caCertPool, + }, + } +} diff --git a/cmd/crc/cmd/start.go b/cmd/crc/cmd/start.go index a00df327ba..8a7853e266 100644 --- a/cmd/crc/cmd/start.go +++ b/cmd/crc/cmd/start.go @@ -208,7 +208,7 @@ func checkIfNewVersionAvailable(noUpdateCheck bool) error { } func newVersionAvailable() (bool, string, string, error) { - release, err := crcversion.GetCRCLatestVersionFromMirror() + release, err := crcversion.GetCRCLatestVersionFromMirror(httpTransport()) if err != nil { return false, "", "", err } diff --git a/pkg/crc/segment/segment.go b/pkg/crc/segment/segment.go index 84c309ed52..06267977e2 100644 --- a/pkg/crc/segment/segment.go +++ b/pkg/crc/segment/segment.go @@ -6,6 +6,7 @@ import ( "fmt" "io/ioutil" "net" + "net/http" "os" "path/filepath" "strings" @@ -30,19 +31,20 @@ type Client struct { telemetryFilePath string } -func NewClient(config *crcConfig.Config) (*Client, error) { - return newCustomClient(config, +func NewClient(config *crcConfig.Config, transport http.RoundTripper) (*Client, error) { + return newCustomClient(config, transport, filepath.Join(constants.GetHomeDir(), ".redhat", "anonymousId"), analytics.DefaultEndpoint) } -func newCustomClient(config *crcConfig.Config, telemetryFilePath, segmentEndpoint string) (*Client, error) { +func newCustomClient(config *crcConfig.Config, transport http.RoundTripper, telemetryFilePath, segmentEndpoint string) (*Client, error) { client, err := analytics.NewWithConfig(WriteKey, analytics.Config{ Endpoint: segmentEndpoint, Logger: &loggingAdapter{}, DefaultContext: &analytics.Context{ IP: net.IPv4(0, 0, 0, 0), }, + Transport: transport, }) if err != nil { return nil, err diff --git a/pkg/crc/segment/segment_test.go b/pkg/crc/segment/segment_test.go index d7d1eacb47..fbb985d619 100644 --- a/pkg/crc/segment/segment_test.go +++ b/pkg/crc/segment/segment_test.go @@ -88,7 +88,7 @@ func TestClientUploadWithConsentAndWithSerializableError(t *testing.T) { uuidFile := filepath.Join(dir, "telemetry") - c, err := newCustomClient(config, uuidFile, server.URL) + c, err := newCustomClient(config, http.DefaultTransport, uuidFile, server.URL) require.NoError(t, err) require.NoError(t, c.UploadCmd(context.Background(), "start", time.Minute, crcErr.ToSerializableError(crcErr.VMNotExist))) @@ -128,7 +128,7 @@ func TestClientUploadWithConsentAndWithoutSerializableError(t *testing.T) { config, err := newTestConfig("yes") require.NoError(t, err) - c, err := newCustomClient(config, filepath.Join(dir, "telemetry"), server.URL) + c, err := newCustomClient(config, http.DefaultTransport, filepath.Join(dir, "telemetry"), server.URL) require.NoError(t, err) require.NoError(t, c.UploadCmd(context.Background(), "start", time.Minute, errors.New("an error occurred"))) @@ -163,7 +163,7 @@ func TestClientUploadWithContext(t *testing.T) { config, err := newTestConfig("yes") require.NoError(t, err) - c, err := newCustomClient(config, filepath.Join(dir, "telemetry"), server.URL) + c, err := newCustomClient(config, http.DefaultTransport, filepath.Join(dir, "telemetry"), server.URL) require.NoError(t, err) ctx := telemetry.NewContext(context.Background()) @@ -193,7 +193,7 @@ func TestClientUploadWithOutConsent(t *testing.T) { config, err := newTestConfig("no") require.NoError(t, err) - c, err := newCustomClient(config, filepath.Join(dir, "telemetry"), server.URL) + c, err := newCustomClient(config, http.DefaultTransport, filepath.Join(dir, "telemetry"), server.URL) require.NoError(t, err) require.NoError(t, c.UploadCmd(context.Background(), "start", time.Second, errors.New("an error occurred"))) diff --git a/pkg/crc/version/version.go b/pkg/crc/version/version.go index d75ec73658..dbdd581867 100644 --- a/pkg/crc/version/version.go +++ b/pkg/crc/version/version.go @@ -83,9 +83,10 @@ func IsMsiBuild() bool { return msiBuild != "false" } -func GetCRCLatestVersionFromMirror() (*CrcReleaseInfo, error) { +func GetCRCLatestVersionFromMirror(transport http.RoundTripper) (*CrcReleaseInfo, error) { client := &http.Client{ - Timeout: 5 * time.Second, + Timeout: 5 * time.Second, + Transport: transport, } req, err := http.NewRequest(http.MethodGet, releaseInfoLink, nil) if err != nil {