From fecc3316977a096d9d20aeb58ff1d08e4b1f76c7 Mon Sep 17 00:00:00 2001 From: hongming Date: Thu, 17 Feb 2022 14:19:38 +0800 Subject: [PATCH] Fix registry verification failed --- .../registries/v2/secret_authenticator.go | 31 +++++++-- .../v2/secret_authenticator_test.go | 67 ++++++++++++++++++- 2 files changed, 90 insertions(+), 8 deletions(-) diff --git a/pkg/models/registries/v2/secret_authenticator.go b/pkg/models/registries/v2/secret_authenticator.go index 9ece9dcf6..d19f0bfab 100644 --- a/pkg/models/registries/v2/secret_authenticator.go +++ b/pkg/models/registries/v2/secret_authenticator.go @@ -2,6 +2,7 @@ package v2 import ( "context" + "crypto/tls" "encoding/json" "fmt" "net/http" @@ -93,9 +94,16 @@ func (s *secretAuthenticator) AuthRegistry(reg string) (bool, error) { } options := make([]name.Option, 0) - if url.Scheme == "http" || s.insecure { + if url.Scheme == "http" { + // allows image references to be fetched without TLS + // transport.NewWithContext will auto-select the right scheme options = append(options, name.Insecure) } + tr := http.DefaultTransport.(*http.Transport).Clone() + // skip tls verify + if s.insecure { + tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } registry, err := name.NewRegistry(url.Host, options...) if err != nil { @@ -103,7 +111,7 @@ func (s *secretAuthenticator) AuthRegistry(reg string) (bool, error) { } ctx := context.TODO() - _, err = transport.NewWithContext(ctx, registry, s, http.DefaultTransport, []string{}) + _, err = transport.NewWithContext(ctx, registry, s, tr, []string{}) if err != nil { return false, err } @@ -113,11 +121,24 @@ func (s *secretAuthenticator) AuthRegistry(reg string) (bool, error) { func (s *secretAuthenticator) Options() []Option { options := make([]Option, 0) - options = append(options, WithAuth(s)) - if s.insecure { + if s.registryScheme() == "http" { options = append(options, Insecure) } - + if s.insecure { + tr := http.DefaultTransport.(*http.Transport).Clone() + tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + options = append(options, WithTransport(tr)) + } return options } + +func (s *secretAuthenticator) registryScheme() string { + for registry := range s.auths { + u, err := url.Parse(registry) + if err == nil { + return u.Scheme + } + } + return "https" +} diff --git a/pkg/models/registries/v2/secret_authenticator_test.go b/pkg/models/registries/v2/secret_authenticator_test.go index deec0beb9..fcdd34ba3 100644 --- a/pkg/models/registries/v2/secret_authenticator_test.go +++ b/pkg/models/registries/v2/secret_authenticator_test.go @@ -1,10 +1,16 @@ package v2 import ( - "fmt" - "testing" - "encoding/base64" + "fmt" + "net/http" + "net/http/httptest" + "testing" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/gexec" "github.com/google/go-cmp/cmp" "github.com/google/go-containerregistry/pkg/authn" @@ -109,3 +115,58 @@ func TestAuthn(t *testing.T) { }) } } + +var ( + registryServer *httptest.Server + tlsRegistryServer *httptest.Server +) + +func TestRegistry(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Registry Test Suite") +} + +var _ = BeforeSuite(func(done Done) { + // anonymous registry + fakeHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write([]byte("ok")) + }) + tlsRegistryServer = httptest.NewTLSServer(fakeHandler) + registryServer = httptest.NewServer(fakeHandler) + close(done) +}, 30) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + gexec.KillAndWait(5 * time.Second) + registryServer.Close() + tlsRegistryServer.Close() +}) + +var _ = Describe("Registry", func() { + Context("Registry", func() { + It("skip TLS certification checks", func() { + secret := buildSecret(tlsRegistryServer.URL, "", "", true) + secretAuthenticator, err := NewSecretAuthenticator(secret) + Expect(err).Should(BeNil()) + _, err = secretAuthenticator.Auth() + Expect(err).Should(BeNil()) + }) + It("self-signed certs are not trusted", func() { + secret := buildSecret(tlsRegistryServer.URL, "", "", false) + secretAuthenticator, err := NewSecretAuthenticator(secret) + Expect(err).Should(BeNil()) + _, err = secretAuthenticator.Auth() + Expect(err).ShouldNot(BeNil()) + }) + It("insecure registry", func() { + // Loopback addr always be insecure, http scheme will be used. + secret := buildSecret(registryServer.URL, "", "", false) + secretAuthenticator, err := NewSecretAuthenticator(secret) + Expect(err).Should(BeNil()) + _, err = secretAuthenticator.Auth() + Expect(err).Should(BeNil()) + }) + }) +})