diff --git a/errors.go b/errors.go index eb332d1bb..7bf720e03 100644 --- a/errors.go +++ b/errors.go @@ -89,3 +89,14 @@ type ErrManifestBlobUnknown struct { func (err ErrManifestBlobUnknown) Error() string { return fmt.Sprintf("unknown blob %v on manifest", err.Digest) } + +// ErrManifestNameInvalid should be used to denote an invalid manifest +// name. Reason may set, indicating the cause of invalidity. +type ErrManifestNameInvalid struct { + Name string + Reason error +} + +func (err ErrManifestNameInvalid) Error() string { + return fmt.Sprintf("manifest name %q invalid: %v", err.Name, err.Reason) +} diff --git a/registry/handlers/images.go b/registry/handlers/images.go index f753f099f..d30fce267 100644 --- a/registry/handlers/images.go +++ b/registry/handlers/images.go @@ -169,6 +169,8 @@ func (imh *imageManifestHandler) PutImageManifest(w http.ResponseWriter, r *http switch verificationError := verificationError.(type) { case distribution.ErrManifestBlobUnknown: imh.Errors = append(imh.Errors, v2.ErrorCodeManifestBlobUnknown.WithDetail(verificationError.Digest)) + case distribution.ErrManifestNameInvalid: + imh.Errors = append(imh.Errors, v2.ErrorCodeNameInvalid.WithDetail(err)) case distribution.ErrManifestUnverified: imh.Errors = append(imh.Errors, v2.ErrorCodeManifestUnverified) default: diff --git a/registry/storage/manifeststore.go b/registry/storage/manifeststore.go index d161fb5a5..024c8e4bb 100644 --- a/registry/storage/manifeststore.go +++ b/registry/storage/manifeststore.go @@ -7,6 +7,7 @@ import ( "github.com/docker/distribution/context" "github.com/docker/distribution/digest" "github.com/docker/distribution/manifest/schema1" + "github.com/docker/distribution/reference" "github.com/docker/libtrust" ) @@ -47,7 +48,7 @@ func SkipLayerVerification(ms distribution.ManifestService) error { ms.skipDependencyVerification = true return nil } - return fmt.Errorf("skip layer verification only valid for manifeststore") + return fmt.Errorf("skip layer verification only valid for manifestStore") } func (ms *manifestStore) Put(manifest *schema1.SignedManifest) error { @@ -106,8 +107,21 @@ func (ms *manifestStore) GetByTag(tag string, options ...distribution.ManifestSe // content, leaving trust policies of that content up to consumers. func (ms *manifestStore) verifyManifest(ctx context.Context, mnfst *schema1.SignedManifest) error { var errs distribution.ErrManifestVerification - if mnfst.Name != ms.repository.Name() { - errs = append(errs, fmt.Errorf("repository name does not match manifest name")) + + if len(mnfst.Name) > reference.NameTotalLengthMax { + errs = append(errs, + distribution.ErrManifestNameInvalid{ + Name: mnfst.Name, + Reason: fmt.Errorf("manifest name must not be more than %v characters", reference.NameTotalLengthMax), + }) + } + + if !reference.NameRegexp.MatchString(mnfst.Name) { + errs = append(errs, + distribution.ErrManifestNameInvalid{ + Name: mnfst.Name, + Reason: fmt.Errorf("invalid manifest name format"), + }) } if len(mnfst.History) != len(mnfst.FSLayers) {