From 3ae0ae54a08bbac657c9194c72f37a886f32bc6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= Date: Sat, 9 Dec 2017 04:12:18 +0100 Subject: [PATCH] Use c/i/types.UnparsedImage for signature verification i.e. defer parsing of the manifest to obtain the config digest only after the signatures have been verified. --- distribution/pull_v2.go | 10 ++++++---- distribution/pull_v2_unix.go | 31 +++++++++++++++++++------------ distribution/pull_v2_windows.go | 10 ++++++---- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/distribution/pull_v2.go b/distribution/pull_v2.go index caf9952472d60..b2354a297d04f 100644 --- a/distribution/pull_v2.go +++ b/distribution/pull_v2.go @@ -13,8 +13,8 @@ import ( "github.com/Sirupsen/logrus" cimagedocker "github.com/containers/image/docker" + ciImage "github.com/containers/image/image" "github.com/containers/image/signature" - "github.com/containers/image/types" "github.com/docker/distribution" "github.com/docker/distribution/digest" "github.com/docker/distribution/manifest/manifestlist" @@ -100,10 +100,11 @@ func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named) (e var layersDownloaded bool if !reference.IsNameOnly(ref) { var err error - ciImage, err := p.ciImage(ctx, ref) + ciImage, closer, err := p.ciImage(ctx, ref) if err != nil { return err } + defer closer.Close() if p.config.SignatureCheck { ref, err = p.checkTrusted(ref, ciImage) if err != nil { @@ -140,10 +141,11 @@ func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named) (e } var ref reference.Named ref = tagRef - ciImage, err := p.ciImage(ctx, ref) + ciImage, closer, err := p.ciImage(ctx, ref) if err != nil { return err } + defer closer.Close() if p.config.SignatureCheck { trustedRef, err := p.checkTrusted(tagRef, ciImage) if err != nil { @@ -375,7 +377,7 @@ func (ld *v2LayerDescriptor) Registered(diffID layer.DiffID) { ld.V2MetadataService.Add(diffID, metadata.V2Metadata{Digest: ld.digest, SourceRepository: ld.repoInfo.FullName()}) } -func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, ciImage types.Image) (tagUpdated bool, err error) { +func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, ciImage *ciImage.UnparsedImage) (tagUpdated bool, err error) { manSvc, err := p.repo.Manifests(ctx) if err != nil { return false, err diff --git a/distribution/pull_v2_unix.go b/distribution/pull_v2_unix.go index d5c4c46a8c4b0..c2c6e9d783018 100644 --- a/distribution/pull_v2_unix.go +++ b/distribution/pull_v2_unix.go @@ -4,11 +4,13 @@ package distribution import ( "fmt" + "io" "path/filepath" "github.com/containers/image/docker" "github.com/containers/image/docker/daemon/signatures" containersImageRef "github.com/containers/image/docker/reference" + ciImage "github.com/containers/image/image" "github.com/containers/image/manifest" "github.com/containers/image/signature" "github.com/containers/image/types" @@ -44,19 +46,19 @@ func configurePolicyContext() (*signature.PolicyContext, error) { return pc, nil } -// ciImage returns a containers/image/types.Image for ref. -func (p *v2Puller) ciImage(c gctx.Context, ref reference.Named) (types.Image, error) { +// ciImage returns a *containers/image/image.UnparsedImage and a close callback for ref. +func (p *v2Puller) ciImage(c gctx.Context, ref reference.Named) (*ciImage.UnparsedImage, io.Closer, error) { // we can't use upstream docker/docker/reference since in projectatomic/docker // we modified docker/docker/reference and it's not doing any normalization. // we instead forked docker/docker/reference in containers/image and we need // this parsing here to make sure signature naming checks are consistent. dockerRef, err := containersImageRef.ParseNormalizedNamed(ref.String()) if err != nil { - return nil, err + return nil, nil, err } imgRef, err := docker.NewReference(dockerRef) if err != nil { - return nil, err + return nil, nil, err } isSecure := (p.endpoint.TLSConfig == nil || !p.endpoint.TLSConfig.InsecureSkipVerify) authConfig := registry.ResolveAuthConfig(p.config.AuthConfigs, p.repoInfo.Index) @@ -73,16 +75,17 @@ func (p *v2Puller) ciImage(c gctx.Context, ref reference.Named) (types.Image, er if p.config.RegistryService.SecureIndex(p.repoInfo.Index.Name) { ctx.DockerCertPath = filepath.Join(registry.CertsDir, p.repoInfo.Index.Name) } - img, err := imgRef.NewImage(ctx) + src, err := imgRef.NewImageSource(ctx) if err != nil { - return nil, err + return nil, nil, err } - return img, nil + unparsed := ciImage.UnparsedInstance(src, nil) + return unparsed, src, nil } -func (p *v2Puller) checkTrusted(ref reference.Named, ciImage types.Image) (reference.Named, error) { +func (p *v2Puller) checkTrusted(ref reference.Named, unparsed types.UnparsedImage) (reference.Named, error) { p.originalRef = ref - allowed, err := p.policyContext.IsRunningImageAllowed(ciImage) + allowed, err := p.policyContext.IsRunningImageAllowed(unparsed) if !allowed { if err != nil { return nil, fmt.Errorf("%s isn't allowed: %v", ref.String(), err) @@ -92,7 +95,7 @@ func (p *v2Puller) checkTrusted(ref reference.Named, ciImage types.Image) (refer if err != nil { return nil, err } - mfst, _, err := ciImage.Manifest() + mfst, _, err := unparsed.Manifest() if err != nil { return nil, err } @@ -108,7 +111,11 @@ func (p *v2Puller) checkTrusted(ref reference.Named, ciImage types.Image) (refer } // storeSignature stores the signatures of ciImage and updates the tag in ciImage.Reference() if necessary. -func (p *v2Puller) storeSignatures(c gctx.Context, ciImage types.Image) error { +func (p *v2Puller) storeSignatures(c gctx.Context, unparsed *ciImage.UnparsedImage) error { + img, err := ciImage.FromUnparsedImage(nil, unparsed) + if err != nil { + return err + } store := signatures.NewStore(nil) - return store.RecordImage(c, ciImage) + return store.RecordImage(c, img) } diff --git a/distribution/pull_v2_windows.go b/distribution/pull_v2_windows.go index f31a1aae8c96c..5f71bcb0999ce 100644 --- a/distribution/pull_v2_windows.go +++ b/distribution/pull_v2_windows.go @@ -5,9 +5,11 @@ package distribution import ( "encoding/json" "fmt" + "io" "net/http" "os" + ciImage "github.com/containers/image/image" "github.com/containers/image/signature" "github.com/containers/image/types" "github.com/docker/distribution" @@ -76,14 +78,14 @@ func configurePolicyContext() (*signature.PolicyContext, error) { return nil, nil } -func (p *v2Puller) ciImage(c gctx.Context, ref reference.Named) (types.Image, error) { - return nil, nil +func (p *v2Puller) ciImage(c gctx.Context, ref reference.Named) (*ciImage.UnparsedImage, io.Closer, error) { + return nil, nil, nil } -func (p *v2Puller) checkTrusted(ref reference.Named, ciImage types.Image) (reference.Named, error) { +func (p *v2Puller) checkTrusted(ref reference.Named, unparsed types.UnparsedImage) (reference.Named, error) { return ref, nil } -func (p *v2Puller) storeSignatures(c gctx.Context, ciImage types.Image) error { +func (p *v2Puller) storeSignatures(c gctx.Context, unparsed *ciImage.UnparsedImage) error { return nil }