Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ RUN apt-get update && apt-get install -y \
parallel \
python-devel \
python-mock \
python-pip
python-pip \
zip \
gpgme-devel \
libassuan-devel

# Get lvm2 source for compiling statically
ENV LVM2_VERSION 2.02.103
Expand Down Expand Up @@ -257,6 +260,17 @@ RUN set -x \
&& go build -v -o /usr/local/bin/rsrc github.com/akavel/rsrc \
&& rm -rf "$GOPATH"

# Install skopeo
ENV SKOPEO_COMMIT v0.1.16
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/projectatomic/skopeo.git "$GOPATH/src/github.com/projectatomic/skopeo" \
&& cd "$GOPATH/src/github.com/projectatomic/skopeo" \
&& git checkout -q "$SKOPEO_COMMIT" \
&& make binary-local \
&& make install GO_MD2MAN="/usr/local/bin/go-md2man" \
&& rm -rf "$GOPATH"

# Wrap all commands in the "docker-in-docker" script to allow nested containers
ENTRYPOINT ["hack/dind"]

Expand Down
7 changes: 5 additions & 2 deletions distribution/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,18 @@ type Puller interface {
// through to the underlying puller implementation for use during the actual
// pull operation.
func newPuller(endpoint registry.APIEndpoint, repoInfo *registry.RepositoryInfo, imagePullConfig *ImagePullConfig) (Puller, error) {
pc, err := configurePolicyContext()
if err != nil {
return nil, err
}
switch endpoint.Version {
case registry.APIVersion2:
return &v2Puller{
V2MetadataService: metadata.NewV2MetadataService(imagePullConfig.MetadataStore),
endpoint: endpoint,
config: imagePullConfig,
repoInfo: repoInfo,
policyContext: pc,
}, nil
case registry.APIVersion1:
return &v1Puller{
Expand Down Expand Up @@ -99,15 +104,13 @@ func Pull(ctx context.Context, ref reference.Named, imagePullConfig *ImagePullCo
fqr, err := reference.QualifyUnqualifiedReference(ref, r)
if err != nil {
errStr := fmt.Sprintf("Failed to fully qualify %q name with %q registry: %v", ref.Name(), r, err)
progress.Message(imagePullConfig.ProgressOutput, "", errStr)
if i == len(registry.DefaultRegistries)-1 {
return fmt.Errorf(errStr)
}
continue
}
if err := pullFromRegistry(ctx, fqr, imagePullConfig); err != nil {
// make sure we get a final "Error response from daemon: "
progress.Message(imagePullConfig.ProgressOutput, "", err.Error())
if i == len(registry.DefaultRegistries)-1 {
return err
}
Expand Down
37 changes: 35 additions & 2 deletions distribution/pull_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"runtime"

"github.com/Sirupsen/logrus"
"github.com/containers/image/signature"
"github.com/docker/distribution"
"github.com/docker/distribution/digest"
"github.com/docker/distribution/manifest/manifestlist"
Expand Down Expand Up @@ -41,6 +42,9 @@ type v2Puller struct {
// confirmedV2 is set to true if we confirm we're talking to a v2
// registry. This is used to limit fallbacks to the v1 protocol.
confirmedV2 bool

policyContext *signature.PolicyContext
originalRef reference.Named
}

func (p *v2Puller) Pull(ctx context.Context, ref reference.Named) (err error) {
Expand Down Expand Up @@ -71,6 +75,11 @@ func (p *v2Puller) Pull(ctx context.Context, ref reference.Named) (err error) {
func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named) (err error) {
var layersDownloaded bool
if !reference.IsNameOnly(ref) {
var err error
ref, err = p.checkTrusted(ctx, ref)
if err != nil {
return allowV1Fallback(err)
}
layersDownloaded, err = p.pullV2Tag(ctx, ref)
if err != nil {
return err
Expand All @@ -93,7 +102,12 @@ func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named) (e
if err != nil {
return err
}
pulledNew, err := p.pullV2Tag(ctx, tagRef)
trustedRef, err := p.checkTrusted(ctx, tagRef)
if err != nil {
p.originalRef = nil
return err
}
pulledNew, err := p.pullV2Tag(ctx, trustedRef)
if err != nil {
// Since this is the pull-all-tags case, don't
// allow an error pulling a particular tag to
Expand All @@ -109,7 +123,9 @@ func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named) (e
}
}

writeStatus(ref.String(), p.config.ProgressOutput, layersDownloaded)
if p.originalRef != nil {
writeStatus(p.originalRef.String(), p.config.ProgressOutput, layersDownloaded)
}

return nil
}
Expand Down Expand Up @@ -287,6 +303,9 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named) (tagUpdat
oldTagImageID, err := p.config.ReferenceStore.Get(ref)
if err == nil {
if oldTagImageID == imageID {
if err := p.addTrustedTag(imageID); err != nil {
return false, err
}
return false, addDigestReference(p.config.ReferenceStore, ref, manifestDigest, imageID)
}
} else if err != reference.ErrDoesNotExist {
Expand All @@ -297,6 +316,9 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named) (tagUpdat
if err = p.config.ReferenceStore.AddDigest(canonical, imageID, true); err != nil {
return false, err
}
if err := p.addTrustedTag(imageID); err != nil {
return false, err
}
} else {
if err = addDigestReference(p.config.ReferenceStore, ref, manifestDigest, imageID); err != nil {
return false, err
Expand All @@ -308,6 +330,17 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named) (tagUpdat
return true, nil
}

func (p *v2Puller) addTrustedTag(id image.ID) error {
if p.policyContext != nil {
if _, ok := p.originalRef.(reference.Canonical); !ok {
if err := p.config.ReferenceStore.AddTag(p.originalRef, id, true); err != nil {
return err
}
}
}
return nil
}

func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Named, unverifiedManifest *schema1.SignedManifest) (imageID image.ID, manifestDigest digest.Digest, err error) {
var verifiedManifest *schema1.Manifest
verifiedManifest, err = verifySchema1Manifest(unverifiedManifest, ref)
Expand Down
77 changes: 77 additions & 0 deletions distribution/pull_v2_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,87 @@
package distribution

import (
"fmt"

"github.com/containers/image/docker"
containersImageRef "github.com/containers/image/docker/reference"
"github.com/containers/image/manifest"
"github.com/containers/image/signature"
"github.com/containers/image/types"
"github.com/docker/distribution/digest"
"github.com/docker/distribution/manifest/schema1"
"github.com/docker/docker/image"
"github.com/docker/docker/reference"
"github.com/docker/docker/registry"
gctx "golang.org/x/net/context"
)

func detectBaseLayer(is image.Store, m *schema1.Manifest, rootFS *image.RootFS) error {
return nil
}

func configurePolicyContext() (*signature.PolicyContext, error) {
defaultPolicy, err := signature.DefaultPolicy(nil)
if err != nil {
return nil, err
}
pc, err := signature.NewPolicyContext(defaultPolicy)
if err != nil {
return nil, err
}
return pc, nil
}

func (p *v2Puller) checkTrusted(c gctx.Context, ref reference.Named) (reference.Named, error) {
p.originalRef = ref
// 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.ParseNamed(ref.String())
if err != nil {
return nil, err
}
imgRef, err := docker.NewReference(dockerRef)
if err != nil {
return nil, err
}
isSecure := (p.endpoint.TLSConfig == nil || !p.endpoint.TLSConfig.InsecureSkipVerify)
authConfig := registry.ResolveAuthConfig(p.config.AuthConfigs, p.repoInfo.Index)
dockerAuthConfig := types.DockerAuthConfig{
Username: authConfig.Username,
Password: authConfig.Password,
}
ctx := &types.SystemContext{
DockerInsecureSkipTLSVerify: !isSecure,
DockerAuthConfig: &dockerAuthConfig,
DockerRegistryUserAgent: registry.DockerUserAgent,
}
img, err := imgRef.NewImage(ctx)
if err != nil {
return nil, err
}
allowed, err := p.policyContext.IsRunningImageAllowed(img)
if !allowed {
if err != nil {
return nil, fmt.Errorf("%s isn't allowed: %v", ref.String(), err)
}
return nil, fmt.Errorf("%s isn't allowed", ref.String())
}
if err != nil {
return nil, err
}
mfst, _, err := img.Manifest()
if err != nil {
return nil, err
}
dgst, err := manifest.Digest(mfst)
if err != nil {
return nil, err
}
ref, err = reference.WithDigest(ref, digest.Digest(dgst))
if err != nil {
return nil, err
}
return ref, nil
}
11 changes: 11 additions & 0 deletions distribution/pull_v2_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import (
"encoding/json"
"fmt"

"github.com/containers/image/signature"
"github.com/docker/distribution/manifest/schema1"
"github.com/docker/docker/image"
"github.com/docker/docker/reference"
gctx "golang.org/x/net/context"
)

func detectBaseLayer(is image.Store, m *schema1.Manifest, rootFS *image.RootFS) error {
Expand All @@ -27,3 +30,11 @@ func detectBaseLayer(is image.Store, m *schema1.Manifest, rootFS *image.RootFS)
}
return fmt.Errorf("Invalid base layer %q", v1img.Parent)
}

func configurePolicyContext() (*signature.PolicyContext, error) {
return nil, nil
}

func (p *v2Puller) checkTrusted(c gctx.Context, ref reference.Named) (reference.Named, error) {
return ref, nil
}
1 change: 1 addition & 0 deletions hack/make.sh
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ bundle() {
source "$SCRIPTDIR/make/$bundle" "$@"
}


main() {
# We want this to fail if the bundles already exist and cannot be removed.
# This is to avoid mixing bundles from different versions of the code.
Expand Down
14 changes: 14 additions & 0 deletions hack/make/.integration-daemon-start
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ if ! command -v docker &> /dev/null; then
false
fi

install_policy() {
file="$1"
target="/etc/containers/policy.json"
if [ "$(go env GOOS)" == "linux" ]; then
if [ ! -e "/etc/containers/policy.json" ]; then
echo "Installing $(basename $file) to ${target}"
mkdir -p /etc/containers
cp -L "$file" "$target"
fi
fi
}

install_policy "$ABS_DEST/../../policy.json"

# intentionally open a couple bogus file descriptors to help test that they get scrubbed in containers
exec 41>&1 42>&2

Expand Down
9 changes: 9 additions & 0 deletions hack/vendor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,13 @@ clone git gopkg.in/fsnotify.v1 v1.2.0
clone git github.com/aws/aws-sdk-go v0.9.9
clone git github.com/vaughan0/go-ini a98ad7ee00ec53921f08832bc06ecf7fd600e6a1

# signatures
clone git github.com/containers/image b6aaec418c03c91344084efd13d14ad80e905cc5
clone git github.com/opencontainers/image-spec 756744a5dcf23a6c8e4b11ef403522ca3ca33fd9
clone git k8s.io/kubernetes 4a3f9c5b19c7ff804cbc1bf37a15c044ca5d2353 https://github.com/openshift/kubernetes
clone git github.com/golang/glog 44145f04b68cf362d9c4df2182967c2275eaefed
clone git github.com/ghodss/yaml 73d445a93680fa1a78ae23a5839bad48f32ba1ee
clone git gopkg.in/yaml.v2 d466437aa4adc35830964cffc5b5f262c63ddcb4
clone git github.com/mtrmac/gpgme master

clean
4 changes: 2 additions & 2 deletions integration-cli/docker_cli_by_digest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
c.Assert(exitStatus, checker.Not(check.Equals), 0)

expectedErrorMsg := fmt.Sprintf("manifest verification failed for digest %s", manifestDigest)
expectedErrorMsg := "manifest unknown"
c.Assert(out, checker.Contains, expectedErrorMsg)
}

Expand Down Expand Up @@ -611,7 +611,7 @@ func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredManifest(c *check.C
out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
c.Assert(exitStatus, checker.Not(check.Equals), 0)

expectedErrorMsg := fmt.Sprintf("image verification failed for digest %s", manifestDigest)
expectedErrorMsg := "manifest unknown"
c.Assert(out, checker.Contains, expectedErrorMsg)
}

Expand Down
Loading