From 7782d04141c2056ffad8ae286eba7e7994e42bc1 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 28 Oct 2020 12:05:40 +0100 Subject: [PATCH] registry: remove v1 authentication Signed-off-by: Sebastiaan van Stijn --- registry/auth.go | 47 ------------------------------------------ registry/service.go | 32 +++++++++++----------------- registry/service_v2.go | 5 +---- 3 files changed, 13 insertions(+), 71 deletions(-) diff --git a/registry/auth.go b/registry/auth.go index bae093ec97..0b2f66cec7 100644 --- a/registry/auth.go +++ b/registry/auth.go @@ -1,7 +1,6 @@ package registry // import "github.com/docker/docker/registry" import ( - "io/ioutil" "net/http" "net/url" "strings" @@ -12,7 +11,6 @@ import ( "github.com/docker/distribution/registry/client/transport" "github.com/docker/docker/api/types" registrytypes "github.com/docker/docker/api/types/registry" - "github.com/docker/docker/errdefs" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -22,51 +20,6 @@ const ( AuthClientID = "docker" ) -// loginV1 tries to register/login to the v1 registry server. -func loginV1(authConfig *types.AuthConfig, apiEndpoint APIEndpoint, userAgent string) (string, string, error) { - registryEndpoint := apiEndpoint.ToV1Endpoint(userAgent, nil) - serverAddress := registryEndpoint.String() - - logrus.Debugf("attempting v1 login to registry endpoint %s", serverAddress) - - if serverAddress == "" { - return "", "", errdefs.System(errors.New("server Error: Server Address not set")) - } - - req, err := http.NewRequest(http.MethodGet, serverAddress+"users/", nil) - if err != nil { - return "", "", err - } - req.SetBasicAuth(authConfig.Username, authConfig.Password) - resp, err := registryEndpoint.client.Do(req) - if err != nil { - // fallback when request could not be completed - return "", "", fallbackError{ - err: err, - } - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return "", "", errdefs.System(err) - } - - switch resp.StatusCode { - case http.StatusOK: - return "Login Succeeded", "", nil - case http.StatusUnauthorized: - return "", "", errdefs.Unauthorized(errors.New("Wrong login/password, please try again")) - case http.StatusForbidden: - // *TODO: Use registry configuration to determine what this says, if anything? - return "", "", errdefs.Forbidden(errors.Errorf("Login: Account is not active. Please see the documentation of the registry %s for instructions how to activate it.", serverAddress)) - case http.StatusInternalServerError: - logrus.Errorf("%s returned status code %d. Response Body :\n%s", req.URL.String(), resp.StatusCode, body) - return "", "", errdefs.System(errors.New("Internal Server Error")) - } - return "", "", errdefs.System(errors.Errorf("Login: %s (Code: %d; Headers: %s)", body, - resp.StatusCode, resp.Header)) -} - type loginCredentialStore struct { authConfig *types.AuthConfig } diff --git a/registry/service.go b/registry/service.go index 08f5c7a4e1..8d8dbd9c17 100644 --- a/registry/service.go +++ b/registry/service.go @@ -120,24 +120,21 @@ func (s *DefaultService) Auth(ctx context.Context, authConfig *types.AuthConfig, return "", "", errdefs.InvalidParameter(errors.Errorf("unable to parse server address: %v", err)) } + // Lookup endpoints for authentication using "LookupPushEndpoints", which + // excludes mirrors to prevent sending credentials of the upstream registry + // to a mirror. endpoints, err := s.LookupPushEndpoints(u.Host) if err != nil { return "", "", errdefs.InvalidParameter(err) } for _, endpoint := range endpoints { - login := loginV2 - if endpoint.Version == APIVersion1 { - login = loginV1 - } - - status, token, err = login(authConfig, endpoint, userAgent) + status, token, err = loginV2(authConfig, endpoint, userAgent) if err == nil { return } if fErr, ok := err.(fallbackError); ok { - err = fErr.err - logrus.Infof("Error logging in to %s endpoint, trying next endpoint: %v", endpoint.Version, err) + logrus.WithError(fErr.err).Infof("Error logging in to endpoint, trying next endpoint") continue } @@ -259,6 +256,7 @@ type APIEndpoint struct { } // ToV1Endpoint returns a V1 API endpoint based on the APIEndpoint +// Deprecated: this function is deprecated and will be removed in a future update func (e APIEndpoint) ToV1Endpoint(userAgent string, metaHeaders http.Header) *V1Endpoint { return newV1Endpoint(*e.URL, e.TLSConfig, userAgent, metaHeaders) } @@ -280,24 +278,22 @@ func (s *DefaultService) tlsConfigForMirror(mirrorURL *url.URL) (*tls.Config, er return s.tlsConfig(mirrorURL.Host) } -// LookupPullEndpoints creates a list of endpoints to try to pull from, in order of preference. -// It gives preference to v2 endpoints over v1, mirrors over the actual -// registry, and HTTPS over plain HTTP. +// LookupPullEndpoints creates a list of v2 endpoints to try to pull from, in order of preference. +// It gives preference to mirrors over the actual registry, and HTTPS over plain HTTP. func (s *DefaultService) LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error) { s.mu.Lock() defer s.mu.Unlock() - return s.lookupEndpoints(hostname) + return s.lookupV2Endpoints(hostname) } -// LookupPushEndpoints creates a list of endpoints to try to push to, in order of preference. -// It gives preference to v2 endpoints over v1, and HTTPS over plain HTTP. -// Mirrors are not included. +// LookupPushEndpoints creates a list of v2 endpoints to try to push to, in order of preference. +// It gives preference to HTTPS over plain HTTP. Mirrors are not included. func (s *DefaultService) LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error) { s.mu.Lock() defer s.mu.Unlock() - allEndpoints, err := s.lookupEndpoints(hostname) + allEndpoints, err := s.lookupV2Endpoints(hostname) if err == nil { for _, endpoint := range allEndpoints { if !endpoint.Mirror { @@ -307,7 +303,3 @@ func (s *DefaultService) LookupPushEndpoints(hostname string) (endpoints []APIEn } return endpoints, err } - -func (s *DefaultService) lookupEndpoints(hostname string) (endpoints []APIEndpoint, err error) { - return s.lookupV2Endpoints(hostname) -} diff --git a/registry/service_v2.go b/registry/service_v2.go index 1a4c9e3105..3e3a5b41ff 100644 --- a/registry/service_v2.go +++ b/registry/service_v2.go @@ -10,7 +10,6 @@ import ( func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) { tlsConfig := tlsconfig.ServerDefault() if hostname == DefaultNamespace || hostname == IndexHostname { - // v2 mirrors for _, mirror := range s.config.Mirrors { if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") { mirror = "https://" + mirror @@ -24,15 +23,13 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp return nil, err } endpoints = append(endpoints, APIEndpoint{ - URL: mirrorURL, - // guess mirrors are v2 + URL: mirrorURL, Version: APIVersion2, Mirror: true, TrimHostname: true, TLSConfig: mirrorTLSConfig, }) } - // v2 registry endpoints = append(endpoints, APIEndpoint{ URL: DefaultV2Registry, Version: APIVersion2,