From 32f167bd9ef051c4dd7d173e82626f5e99df9033 Mon Sep 17 00:00:00 2001 From: Riyaz Faizullabhoy Date: Wed, 31 May 2017 16:42:42 -0700 Subject: [PATCH 1/3] trust: fix splitting on tags and digests and add tests Signed-off-by: Riyaz Faizullabhoy --- cmd/moby/build.go | 6 ++++-- cmd/moby/trust_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 cmd/moby/trust_test.go diff --git a/cmd/moby/build.go b/cmd/moby/build.go index 3237ef94e..e88b1769a 100644 --- a/cmd/moby/build.go +++ b/cmd/moby/build.go @@ -137,11 +137,13 @@ func enforceContentTrust(fullImageName string, config *TrustConfig) bool { } // Also check for an image name only match // by removing a possible tag (with possibly added digest): - if img == strings.TrimSuffix(fullImageName, ":") { + imgAndTag := strings.Split(fullImageName, ":") + if len(imgAndTag) >= 2 && img == imgAndTag[0] { return true } // and by removing a possible digest: - if img == strings.TrimSuffix(fullImageName, "@sha256:") { + imgAndDigest := strings.Split(fullImageName, "@sha256:") + if len(imgAndDigest) >= 2 && img == imgAndDigest[0] { return true } } diff --git a/cmd/moby/trust_test.go b/cmd/moby/trust_test.go new file mode 100644 index 000000000..681e70f01 --- /dev/null +++ b/cmd/moby/trust_test.go @@ -0,0 +1,46 @@ +package main + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestEnforceContentTrust(t *testing.T) { + // Simple positive and negative cases for Image subkey + require.True(t, enforceContentTrust("image", &TrustConfig{Image: []string{"image"}})) + require.True(t, enforceContentTrust("image", &TrustConfig{Image: []string{"more", "than", "one", "image"}})) + require.True(t, enforceContentTrust("image", &TrustConfig{Image: []string{"more", "than", "one", "image"}, Org: []string{"random", "orgs"}})) + + require.False(t, enforceContentTrust("image", &TrustConfig{})) + require.False(t, enforceContentTrust("image", &TrustConfig{Image: []string{"not", "in", "here!"}})) + require.False(t, enforceContentTrust("image", &TrustConfig{Image: []string{"not", "in", "here!"}, Org: []string{""}})) + + // Tests for Image subkey with tags + require.True(t, enforceContentTrust("image:tag", &TrustConfig{Image: []string{"image:tag"}})) + require.True(t, enforceContentTrust("image:tag", &TrustConfig{Image: []string{"image"}})) + require.False(t, enforceContentTrust("image:tag", &TrustConfig{Image: []string{"image:otherTag"}})) + require.False(t, enforceContentTrust("image:tag", &TrustConfig{Image: []string{"image@sha256:abc123"}})) + + // Tests for Image subkey with digests + require.True(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image@sha256:abc123"}})) + require.True(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image"}})) + require.False(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image:Tag"}})) + require.False(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image@sha256:def456"}})) + + // Tests for Image subkey with digests + require.True(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image@sha256:abc123"}})) + require.True(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image"}})) + require.False(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image:Tag"}})) + require.False(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image@sha256:def456"}})) + + // Tests for Org subkey + require.True(t, enforceContentTrust("linuxkit/image", &TrustConfig{Image: []string{"notImage"}, Org: []string{"linuxkit"}})) + require.True(t, enforceContentTrust("linuxkit/differentImage", &TrustConfig{Image: []string{}, Org: []string{"linuxkit"}})) + require.True(t, enforceContentTrust("linuxkit/differentImage:tag", &TrustConfig{Image: []string{}, Org: []string{"linuxkit"}})) + require.True(t, enforceContentTrust("linuxkit/differentImage@sha256:abc123", &TrustConfig{Image: []string{}, Org: []string{"linuxkit"}})) + + require.False(t, enforceContentTrust("linuxkit/differentImage", &TrustConfig{Image: []string{}, Org: []string{"notlinuxkit"}})) + require.False(t, enforceContentTrust("linuxkit/differentImage:tag", &TrustConfig{Image: []string{}, Org: []string{"notlinuxkit"}})) + require.False(t, enforceContentTrust("linuxkit/differentImage@sha256:abc123", &TrustConfig{Image: []string{}, Org: []string{"notlinuxkit"}})) +} From 99eeb981a725084f8d7b826c23b7aea6e8869779 Mon Sep 17 00:00:00 2001 From: Riyaz Faizullabhoy Date: Wed, 31 May 2017 17:22:31 -0700 Subject: [PATCH 2/3] trust: improve org checks to enable library official repo checks Signed-off-by: Riyaz Faizullabhoy --- cmd/moby/build.go | 18 +++++++++++++++++- cmd/moby/trust_test.go | 6 ++++++ test/test.yml | 3 +-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/cmd/moby/build.go b/cmd/moby/build.go index e88b1769a..8c278446d 100644 --- a/cmd/moby/build.go +++ b/cmd/moby/build.go @@ -149,7 +149,23 @@ func enforceContentTrust(fullImageName string, config *TrustConfig) bool { } for _, org := range config.Org { - if strings.HasPrefix(fullImageName, org+"/") { + var imgOrg string + splitName := strings.Split(fullImageName, "/") + switch len(splitName) { + case 0: + // if the image is empty, return false + return false + case 1: + // for single names like nginx, use library + imgOrg = "library" + case 2: + // for names that assume docker hub, like linxukit/alpine, take the first split + imgOrg = splitName[0] + default: + // for names that include the registry, the second piece is the org, ex: docker.io/library/alpine + imgOrg = splitName[1] + } + if imgOrg == org { return true } } diff --git a/cmd/moby/trust_test.go b/cmd/moby/trust_test.go index 681e70f01..c175f8026 100644 --- a/cmd/moby/trust_test.go +++ b/cmd/moby/trust_test.go @@ -43,4 +43,10 @@ func TestEnforceContentTrust(t *testing.T) { require.False(t, enforceContentTrust("linuxkit/differentImage", &TrustConfig{Image: []string{}, Org: []string{"notlinuxkit"}})) require.False(t, enforceContentTrust("linuxkit/differentImage:tag", &TrustConfig{Image: []string{}, Org: []string{"notlinuxkit"}})) require.False(t, enforceContentTrust("linuxkit/differentImage@sha256:abc123", &TrustConfig{Image: []string{}, Org: []string{"notlinuxkit"}})) + + // Tests for Org with library organization + require.True(t, enforceContentTrust("nginx", &TrustConfig{Image: []string{}, Org: []string{"library"}})) + require.True(t, enforceContentTrust("nginx:alpine", &TrustConfig{Image: []string{}, Org: []string{"library"}})) + require.True(t, enforceContentTrust("library/nginx:alpine", &TrustConfig{Image: []string{}, Org: []string{"library"}})) + require.False(t, enforceContentTrust("nginx", &TrustConfig{Image: []string{}, Org: []string{"notLibrary"}})) } diff --git a/test/test.yml b/test/test.yml index b80acf476..41488d860 100644 --- a/test/test.yml +++ b/test/test.yml @@ -31,6 +31,5 @@ files: contents: '{"debug": true}' trust: org: + - library - linuxkit - image: - - nginx:alpine From e0fc007b5a88b3f90459da0e8a4f5036969fd3ef Mon Sep 17 00:00:00 2001 From: Riyaz Faizullabhoy Date: Thu, 1 Jun 2017 11:20:27 -0700 Subject: [PATCH 3/3] test cases with default golang lib Signed-off-by: Riyaz Faizullabhoy --- cmd/moby/trust_test.go | 90 ++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/cmd/moby/trust_test.go b/cmd/moby/trust_test.go index c175f8026..36d1f2da8 100644 --- a/cmd/moby/trust_test.go +++ b/cmd/moby/trust_test.go @@ -1,52 +1,58 @@ package main -import ( - "testing" - - "github.com/stretchr/testify/require" -) +import "testing" func TestEnforceContentTrust(t *testing.T) { - // Simple positive and negative cases for Image subkey - require.True(t, enforceContentTrust("image", &TrustConfig{Image: []string{"image"}})) - require.True(t, enforceContentTrust("image", &TrustConfig{Image: []string{"more", "than", "one", "image"}})) - require.True(t, enforceContentTrust("image", &TrustConfig{Image: []string{"more", "than", "one", "image"}, Org: []string{"random", "orgs"}})) + type enforceContentTrustCase struct { + result bool + imageName string + trustConfig *TrustConfig + } + testCases := []enforceContentTrustCase{ + // Simple positive and negative cases for Image subkey + {true, "image", &TrustConfig{Image: []string{"image"}}}, + {true, "image", &TrustConfig{Image: []string{"more", "than", "one", "image"}}}, + {true, "image", &TrustConfig{Image: []string{"more", "than", "one", "image"}, Org: []string{"random", "orgs"}}}, + {false, "image", &TrustConfig{}}, + {false, "image", &TrustConfig{Image: []string{"not", "in", "here!"}}}, + {false, "image", &TrustConfig{Image: []string{"not", "in", "here!"}, Org: []string{""}}}, - require.False(t, enforceContentTrust("image", &TrustConfig{})) - require.False(t, enforceContentTrust("image", &TrustConfig{Image: []string{"not", "in", "here!"}})) - require.False(t, enforceContentTrust("image", &TrustConfig{Image: []string{"not", "in", "here!"}, Org: []string{""}})) + // Tests for Image subkey with tags + {true, "image:tag", &TrustConfig{Image: []string{"image:tag"}}}, + {true, "image:tag", &TrustConfig{Image: []string{"image"}}}, + {false, "image:tag", &TrustConfig{Image: []string{"image:otherTag"}}}, + {false, "image:tag", &TrustConfig{Image: []string{"image@sha256:abc123"}}}, - // Tests for Image subkey with tags - require.True(t, enforceContentTrust("image:tag", &TrustConfig{Image: []string{"image:tag"}})) - require.True(t, enforceContentTrust("image:tag", &TrustConfig{Image: []string{"image"}})) - require.False(t, enforceContentTrust("image:tag", &TrustConfig{Image: []string{"image:otherTag"}})) - require.False(t, enforceContentTrust("image:tag", &TrustConfig{Image: []string{"image@sha256:abc123"}})) + // Tests for Image subkey with digests + {true, "image@sha256:abc123", &TrustConfig{Image: []string{"image@sha256:abc123"}}}, + {true, "image@sha256:abc123", &TrustConfig{Image: []string{"image"}}}, + {false, "image@sha256:abc123", &TrustConfig{Image: []string{"image:Tag"}}}, + {false, "image@sha256:abc123", &TrustConfig{Image: []string{"image@sha256:def456"}}}, - // Tests for Image subkey with digests - require.True(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image@sha256:abc123"}})) - require.True(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image"}})) - require.False(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image:Tag"}})) - require.False(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image@sha256:def456"}})) + // Tests for Image subkey with digests + {true, "image@sha256:abc123", &TrustConfig{Image: []string{"image@sha256:abc123"}}}, + {true, "image@sha256:abc123", &TrustConfig{Image: []string{"image"}}}, + {false, "image@sha256:abc123", &TrustConfig{Image: []string{"image:Tag"}}}, + {false, "image@sha256:abc123", &TrustConfig{Image: []string{"image@sha256:def456"}}}, - // Tests for Image subkey with digests - require.True(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image@sha256:abc123"}})) - require.True(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image"}})) - require.False(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image:Tag"}})) - require.False(t, enforceContentTrust("image@sha256:abc123", &TrustConfig{Image: []string{"image@sha256:def456"}})) + // Tests for Org subkey + {true, "linuxkit/image", &TrustConfig{Image: []string{"notImage"}, Org: []string{"linuxkit"}}}, + {true, "linuxkit/differentImage", &TrustConfig{Image: []string{}, Org: []string{"linuxkit"}}}, + {true, "linuxkit/differentImage:tag", &TrustConfig{Image: []string{}, Org: []string{"linuxkit"}}}, + {true, "linuxkit/differentImage@sha256:abc123", &TrustConfig{Image: []string{}, Org: []string{"linuxkit"}}}, + {false, "linuxkit/differentImage", &TrustConfig{Image: []string{}, Org: []string{"notlinuxkit"}}}, + {false, "linuxkit/differentImage:tag", &TrustConfig{Image: []string{}, Org: []string{"notlinuxkit"}}}, + {false, "linuxkit/differentImage@sha256:abc123", &TrustConfig{Image: []string{}, Org: []string{"notlinuxkit"}}}, - // Tests for Org subkey - require.True(t, enforceContentTrust("linuxkit/image", &TrustConfig{Image: []string{"notImage"}, Org: []string{"linuxkit"}})) - require.True(t, enforceContentTrust("linuxkit/differentImage", &TrustConfig{Image: []string{}, Org: []string{"linuxkit"}})) - require.True(t, enforceContentTrust("linuxkit/differentImage:tag", &TrustConfig{Image: []string{}, Org: []string{"linuxkit"}})) - require.True(t, enforceContentTrust("linuxkit/differentImage@sha256:abc123", &TrustConfig{Image: []string{}, Org: []string{"linuxkit"}})) - - require.False(t, enforceContentTrust("linuxkit/differentImage", &TrustConfig{Image: []string{}, Org: []string{"notlinuxkit"}})) - require.False(t, enforceContentTrust("linuxkit/differentImage:tag", &TrustConfig{Image: []string{}, Org: []string{"notlinuxkit"}})) - require.False(t, enforceContentTrust("linuxkit/differentImage@sha256:abc123", &TrustConfig{Image: []string{}, Org: []string{"notlinuxkit"}})) - - // Tests for Org with library organization - require.True(t, enforceContentTrust("nginx", &TrustConfig{Image: []string{}, Org: []string{"library"}})) - require.True(t, enforceContentTrust("nginx:alpine", &TrustConfig{Image: []string{}, Org: []string{"library"}})) - require.True(t, enforceContentTrust("library/nginx:alpine", &TrustConfig{Image: []string{}, Org: []string{"library"}})) - require.False(t, enforceContentTrust("nginx", &TrustConfig{Image: []string{}, Org: []string{"notLibrary"}})) + // Tests for Org with library organization + {true, "nginx", &TrustConfig{Image: []string{}, Org: []string{"library"}}}, + {true, "nginx:alpine", &TrustConfig{Image: []string{}, Org: []string{"library"}}}, + {true, "library/nginx:alpine", &TrustConfig{Image: []string{}, Org: []string{"library"}}}, + {false, "nginx", &TrustConfig{Image: []string{}, Org: []string{"notLibrary"}}}, + } + for _, testCase := range testCases { + if enforceContentTrust(testCase.imageName, testCase.trustConfig) != testCase.result { + t.Errorf("incorrect trust enforcement result for %s against configuration %v, expected: %v", testCase.imageName, testCase.trustConfig, testCase.result) + } + } }