registry: remove v1 authentication

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2020-10-28 12:05:40 +01:00
parent ab47fd2f72
commit 7782d04141
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
3 changed files with 13 additions and 71 deletions

View File

@ -1,7 +1,6 @@
package registry // import "github.com/docker/docker/registry" package registry // import "github.com/docker/docker/registry"
import ( import (
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
@ -12,7 +11,6 @@ import (
"github.com/docker/distribution/registry/client/transport" "github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry" registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -22,51 +20,6 @@ const (
AuthClientID = "docker" 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 { type loginCredentialStore struct {
authConfig *types.AuthConfig authConfig *types.AuthConfig
} }

View File

@ -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)) 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) endpoints, err := s.LookupPushEndpoints(u.Host)
if err != nil { if err != nil {
return "", "", errdefs.InvalidParameter(err) return "", "", errdefs.InvalidParameter(err)
} }
for _, endpoint := range endpoints { for _, endpoint := range endpoints {
login := loginV2 status, token, err = loginV2(authConfig, endpoint, userAgent)
if endpoint.Version == APIVersion1 {
login = loginV1
}
status, token, err = login(authConfig, endpoint, userAgent)
if err == nil { if err == nil {
return return
} }
if fErr, ok := err.(fallbackError); ok { if fErr, ok := err.(fallbackError); ok {
err = fErr.err logrus.WithError(fErr.err).Infof("Error logging in to endpoint, trying next endpoint")
logrus.Infof("Error logging in to %s endpoint, trying next endpoint: %v", endpoint.Version, err)
continue continue
} }
@ -259,6 +256,7 @@ type APIEndpoint struct {
} }
// ToV1Endpoint returns a V1 API endpoint based on the APIEndpoint // 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 { func (e APIEndpoint) ToV1Endpoint(userAgent string, metaHeaders http.Header) *V1Endpoint {
return newV1Endpoint(*e.URL, e.TLSConfig, userAgent, metaHeaders) 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) return s.tlsConfig(mirrorURL.Host)
} }
// LookupPullEndpoints creates a list of endpoints to try to pull from, in order of preference. // LookupPullEndpoints creates a list of v2 endpoints to try to pull from, in order of preference.
// It gives preference to v2 endpoints over v1, mirrors over the actual // It gives preference to mirrors over the actual registry, and HTTPS over plain HTTP.
// registry, and HTTPS over plain HTTP.
func (s *DefaultService) LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error) { func (s *DefaultService) LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error) {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() 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. // LookupPushEndpoints creates a list of v2 endpoints to try to push to, in order of preference.
// It gives preference to v2 endpoints over v1, and HTTPS over plain HTTP. // It gives preference to HTTPS over plain HTTP. Mirrors are not included.
// Mirrors are not included.
func (s *DefaultService) LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error) { func (s *DefaultService) LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error) {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
allEndpoints, err := s.lookupEndpoints(hostname) allEndpoints, err := s.lookupV2Endpoints(hostname)
if err == nil { if err == nil {
for _, endpoint := range allEndpoints { for _, endpoint := range allEndpoints {
if !endpoint.Mirror { if !endpoint.Mirror {
@ -307,7 +303,3 @@ func (s *DefaultService) LookupPushEndpoints(hostname string) (endpoints []APIEn
} }
return endpoints, err return endpoints, err
} }
func (s *DefaultService) lookupEndpoints(hostname string) (endpoints []APIEndpoint, err error) {
return s.lookupV2Endpoints(hostname)
}

View File

@ -10,7 +10,6 @@ import (
func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) { func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) {
tlsConfig := tlsconfig.ServerDefault() tlsConfig := tlsconfig.ServerDefault()
if hostname == DefaultNamespace || hostname == IndexHostname { if hostname == DefaultNamespace || hostname == IndexHostname {
// v2 mirrors
for _, mirror := range s.config.Mirrors { for _, mirror := range s.config.Mirrors {
if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") { if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") {
mirror = "https://" + mirror mirror = "https://" + mirror
@ -24,15 +23,13 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp
return nil, err return nil, err
} }
endpoints = append(endpoints, APIEndpoint{ endpoints = append(endpoints, APIEndpoint{
URL: mirrorURL, URL: mirrorURL,
// guess mirrors are v2
Version: APIVersion2, Version: APIVersion2,
Mirror: true, Mirror: true,
TrimHostname: true, TrimHostname: true,
TLSConfig: mirrorTLSConfig, TLSConfig: mirrorTLSConfig,
}) })
} }
// v2 registry
endpoints = append(endpoints, APIEndpoint{ endpoints = append(endpoints, APIEndpoint{
URL: DefaultV2Registry, URL: DefaultV2Registry,
Version: APIVersion2, Version: APIVersion2,