registry: treat basic-auth 401 as unauthorized - #7254
Conversation
Client-side login (daemon down) was wrapping a 401 as a plain error, so Auth() moved on to the next endpoint. That can print Login Succeeded if the HTTP fallback happens to answer 200. Fixes docker#7237 Signed-off-by: Dean Chen <862469039@qq.com>
| resp, err := loginClient.Do(req) | ||
| if err != nil { | ||
| err = translateV2AuthError(err) | ||
| return "", err | ||
| } |
There was a problem hiding this comment.
Shouldn't translateV2AuthError handle this already?
cli/internal/registry/errors.go
Lines 14 to 23 in ff3273f
There was a problem hiding this comment.
it only unwraps a url.Error from Do() (the distribution errcode path). a 401 status never hits that, so I switched this to errhttp.ToNative.
| if resp.StatusCode != http.StatusOK { | ||
| // TODO(dmcgowan): Attempt to further interpret result, status code and error code string | ||
| return "", fmt.Errorf("login attempt to %s failed with status: %d %s", endpointStr, resp.StatusCode, http.StatusText(resp.StatusCode)) | ||
| err := fmt.Errorf("login attempt to %s failed with status: %d %s", endpointStr, resp.StatusCode, http.StatusText(resp.StatusCode)) | ||
| if resp.StatusCode == http.StatusUnauthorized { | ||
| return "", unauthorizedErr{err} | ||
| } | ||
| return "", err |
There was a problem hiding this comment.
Possibly we should use github.com/containerd/errdefs/errhttp.ToNative here
cli/vendor/github.com/containerd/errdefs/pkg/errhttp/http.go
Lines 68 to 96 in ff3273f
But probably wrap / decorate it after that
func TestError(t *testing.T) {
err := errhttp.ToNative(401)
endpointStr := "example.com"
err = fmt.Errorf("login attempt to %s failed: %w", endpointStr, err)
assert.Check(t, is.ErrorType(err, errdefs.IsUnauthorized))
}There was a problem hiding this comment.
yeah, used that and wrapped it so the endpoint still shows up in the error.
translateV2AuthError only unwraps a url.Error from Do(); a 401 status never went through it. Use errhttp.ToNative so Auth() treats that 401 as unauthorized and stops. Signed-off-by: Dean Chen <862469039@qq.com>
daemon-less
docker loginwas turning a 401 into a plain error, soAuth()tried the next endpoint. against a Basic-Auth registry that can printLogin Succeededfor a wrong password (the HTTP fallback answering 200).mark 401 as unauthorized and stop.
Fixes #7237