Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -1,7 +1,6 @@ |
| 1 | 1 |
package registry // import "github.com/docker/docker/registry" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "io/ioutil" |
|
| 5 | 4 |
"net/http" |
| 6 | 5 |
"net/url" |
| 7 | 6 |
"strings" |
| ... | ... |
@@ -12,7 +11,6 @@ import ( |
| 12 | 12 |
"github.com/docker/distribution/registry/client/transport" |
| 13 | 13 |
"github.com/docker/docker/api/types" |
| 14 | 14 |
registrytypes "github.com/docker/docker/api/types/registry" |
| 15 |
- "github.com/docker/docker/errdefs" |
|
| 16 | 15 |
"github.com/pkg/errors" |
| 17 | 16 |
"github.com/sirupsen/logrus" |
| 18 | 17 |
) |
| ... | ... |
@@ -22,51 +20,6 @@ const ( |
| 22 | 22 |
AuthClientID = "docker" |
| 23 | 23 |
) |
| 24 | 24 |
|
| 25 |
-// loginV1 tries to register/login to the v1 registry server. |
|
| 26 |
-func loginV1(authConfig *types.AuthConfig, apiEndpoint APIEndpoint, userAgent string) (string, string, error) {
|
|
| 27 |
- registryEndpoint := apiEndpoint.ToV1Endpoint(userAgent, nil) |
|
| 28 |
- serverAddress := registryEndpoint.String() |
|
| 29 |
- |
|
| 30 |
- logrus.Debugf("attempting v1 login to registry endpoint %s", serverAddress)
|
|
| 31 |
- |
|
| 32 |
- if serverAddress == "" {
|
|
| 33 |
- return "", "", errdefs.System(errors.New("server Error: Server Address not set"))
|
|
| 34 |
- } |
|
| 35 |
- |
|
| 36 |
- req, err := http.NewRequest(http.MethodGet, serverAddress+"users/", nil) |
|
| 37 |
- if err != nil {
|
|
| 38 |
- return "", "", err |
|
| 39 |
- } |
|
| 40 |
- req.SetBasicAuth(authConfig.Username, authConfig.Password) |
|
| 41 |
- resp, err := registryEndpoint.client.Do(req) |
|
| 42 |
- if err != nil {
|
|
| 43 |
- // fallback when request could not be completed |
|
| 44 |
- return "", "", fallbackError{
|
|
| 45 |
- err: err, |
|
| 46 |
- } |
|
| 47 |
- } |
|
| 48 |
- defer resp.Body.Close() |
|
| 49 |
- body, err := ioutil.ReadAll(resp.Body) |
|
| 50 |
- if err != nil {
|
|
| 51 |
- return "", "", errdefs.System(err) |
|
| 52 |
- } |
|
| 53 |
- |
|
| 54 |
- switch resp.StatusCode {
|
|
| 55 |
- case http.StatusOK: |
|
| 56 |
- return "Login Succeeded", "", nil |
|
| 57 |
- case http.StatusUnauthorized: |
|
| 58 |
- return "", "", errdefs.Unauthorized(errors.New("Wrong login/password, please try again"))
|
|
| 59 |
- case http.StatusForbidden: |
|
| 60 |
- // *TODO: Use registry configuration to determine what this says, if anything? |
|
| 61 |
- 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))
|
|
| 62 |
- case http.StatusInternalServerError: |
|
| 63 |
- logrus.Errorf("%s returned status code %d. Response Body :\n%s", req.URL.String(), resp.StatusCode, body)
|
|
| 64 |
- return "", "", errdefs.System(errors.New("Internal Server Error"))
|
|
| 65 |
- } |
|
| 66 |
- return "", "", errdefs.System(errors.Errorf("Login: %s (Code: %d; Headers: %s)", body,
|
|
| 67 |
- resp.StatusCode, resp.Header)) |
|
| 68 |
-} |
|
| 69 |
- |
|
| 70 | 25 |
type loginCredentialStore struct {
|
| 71 | 26 |
authConfig *types.AuthConfig |
| 72 | 27 |
} |
| ... | ... |
@@ -120,24 +120,21 @@ func (s *DefaultService) Auth(ctx context.Context, authConfig *types.AuthConfig, |
| 120 | 120 |
return "", "", errdefs.InvalidParameter(errors.Errorf("unable to parse server address: %v", err))
|
| 121 | 121 |
} |
| 122 | 122 |
|
| 123 |
+ // Lookup endpoints for authentication using "LookupPushEndpoints", which |
|
| 124 |
+ // excludes mirrors to prevent sending credentials of the upstream registry |
|
| 125 |
+ // to a mirror. |
|
| 123 | 126 |
endpoints, err := s.LookupPushEndpoints(u.Host) |
| 124 | 127 |
if err != nil {
|
| 125 | 128 |
return "", "", errdefs.InvalidParameter(err) |
| 126 | 129 |
} |
| 127 | 130 |
|
| 128 | 131 |
for _, endpoint := range endpoints {
|
| 129 |
- login := loginV2 |
|
| 130 |
- if endpoint.Version == APIVersion1 {
|
|
| 131 |
- login = loginV1 |
|
| 132 |
- } |
|
| 133 |
- |
|
| 134 |
- status, token, err = login(authConfig, endpoint, userAgent) |
|
| 132 |
+ status, token, err = loginV2(authConfig, endpoint, userAgent) |
|
| 135 | 133 |
if err == nil {
|
| 136 | 134 |
return |
| 137 | 135 |
} |
| 138 | 136 |
if fErr, ok := err.(fallbackError); ok {
|
| 139 |
- err = fErr.err |
|
| 140 |
- logrus.Infof("Error logging in to %s endpoint, trying next endpoint: %v", endpoint.Version, err)
|
|
| 137 |
+ logrus.WithError(fErr.err).Infof("Error logging in to endpoint, trying next endpoint")
|
|
| 141 | 138 |
continue |
| 142 | 139 |
} |
| 143 | 140 |
|
| ... | ... |
@@ -259,6 +256,7 @@ type APIEndpoint struct {
|
| 259 | 259 |
} |
| 260 | 260 |
|
| 261 | 261 |
// ToV1Endpoint returns a V1 API endpoint based on the APIEndpoint |
| 262 |
+// Deprecated: this function is deprecated and will be removed in a future update |
|
| 262 | 263 |
func (e APIEndpoint) ToV1Endpoint(userAgent string, metaHeaders http.Header) *V1Endpoint {
|
| 263 | 264 |
return newV1Endpoint(*e.URL, e.TLSConfig, userAgent, metaHeaders) |
| 264 | 265 |
} |
| ... | ... |
@@ -280,24 +278,22 @@ func (s *DefaultService) tlsConfigForMirror(mirrorURL *url.URL) (*tls.Config, er |
| 280 | 280 |
return s.tlsConfig(mirrorURL.Host) |
| 281 | 281 |
} |
| 282 | 282 |
|
| 283 |
-// LookupPullEndpoints creates a list of endpoints to try to pull from, in order of preference. |
|
| 284 |
-// It gives preference to v2 endpoints over v1, mirrors over the actual |
|
| 285 |
-// registry, and HTTPS over plain HTTP. |
|
| 283 |
+// LookupPullEndpoints creates a list of v2 endpoints to try to pull from, in order of preference. |
|
| 284 |
+// It gives preference to mirrors over the actual registry, and HTTPS over plain HTTP. |
|
| 286 | 285 |
func (s *DefaultService) LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error) {
|
| 287 | 286 |
s.mu.Lock() |
| 288 | 287 |
defer s.mu.Unlock() |
| 289 | 288 |
|
| 290 |
- return s.lookupEndpoints(hostname) |
|
| 289 |
+ return s.lookupV2Endpoints(hostname) |
|
| 291 | 290 |
} |
| 292 | 291 |
|
| 293 |
-// LookupPushEndpoints creates a list of endpoints to try to push to, in order of preference. |
|
| 294 |
-// It gives preference to v2 endpoints over v1, and HTTPS over plain HTTP. |
|
| 295 |
-// Mirrors are not included. |
|
| 292 |
+// LookupPushEndpoints creates a list of v2 endpoints to try to push to, in order of preference. |
|
| 293 |
+// It gives preference to HTTPS over plain HTTP. Mirrors are not included. |
|
| 296 | 294 |
func (s *DefaultService) LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error) {
|
| 297 | 295 |
s.mu.Lock() |
| 298 | 296 |
defer s.mu.Unlock() |
| 299 | 297 |
|
| 300 |
- allEndpoints, err := s.lookupEndpoints(hostname) |
|
| 298 |
+ allEndpoints, err := s.lookupV2Endpoints(hostname) |
|
| 301 | 299 |
if err == nil {
|
| 302 | 300 |
for _, endpoint := range allEndpoints {
|
| 303 | 301 |
if !endpoint.Mirror {
|
| ... | ... |
@@ -307,7 +303,3 @@ func (s *DefaultService) LookupPushEndpoints(hostname string) (endpoints []APIEn |
| 307 | 307 |
} |
| 308 | 308 |
return endpoints, err |
| 309 | 309 |
} |
| 310 |
- |
|
| 311 |
-func (s *DefaultService) lookupEndpoints(hostname string) (endpoints []APIEndpoint, err error) {
|
|
| 312 |
- return s.lookupV2Endpoints(hostname) |
|
| 313 |
-} |
| ... | ... |
@@ -10,7 +10,6 @@ import ( |
| 10 | 10 |
func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) {
|
| 11 | 11 |
tlsConfig := tlsconfig.ServerDefault() |
| 12 | 12 |
if hostname == DefaultNamespace || hostname == IndexHostname {
|
| 13 |
- // v2 mirrors |
|
| 14 | 13 |
for _, mirror := range s.config.Mirrors {
|
| 15 | 14 |
if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") {
|
| 16 | 15 |
mirror = "https://" + mirror |
| ... | ... |
@@ -24,15 +23,13 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp |
| 24 | 24 |
return nil, err |
| 25 | 25 |
} |
| 26 | 26 |
endpoints = append(endpoints, APIEndpoint{
|
| 27 |
- URL: mirrorURL, |
|
| 28 |
- // guess mirrors are v2 |
|
| 27 |
+ URL: mirrorURL, |
|
| 29 | 28 |
Version: APIVersion2, |
| 30 | 29 |
Mirror: true, |
| 31 | 30 |
TrimHostname: true, |
| 32 | 31 |
TLSConfig: mirrorTLSConfig, |
| 33 | 32 |
}) |
| 34 | 33 |
} |
| 35 |
- // v2 registry |
|
| 36 | 34 |
endpoints = append(endpoints, APIEndpoint{
|
| 37 | 35 |
URL: DefaultV2Registry, |
| 38 | 36 |
Version: APIVersion2, |