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
2 changes: 1 addition & 1 deletion hack/vendor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ clone git github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42
clone git github.com/flynn-archive/go-shlex 3f9db97f856818214da2e1057f8ad84803971cff

# signatures
clone git github.com/containers/image 6f5f102da5ee57ddca4f23d2c0e4cc7da9cb54b4
clone git github.com/containers/image untagged-reference-sig-check https://github.com/mtrmac/image
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
Expand Down
5 changes: 4 additions & 1 deletion integration-cli/docker_cli_pull_local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,10 @@ func (s *DockerRegistriesSuite) TestPullWithPolicy(c *check.C) {
"docker": {
"%s/busybox": [
{
"referencesByDigest": "reject",
"signedIdentity": {
"type": "matchExact",
"allowReferencesByDigest": false
},
"type": "signedBy",
"keyType": "GPGKeys",
"keyPath": "/root/personal-pubkey.gpg"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ func (pr *prSignedBy) UnmarshalJSON(data []byte) error {
return InvalidPolicyFormatError(fmt.Sprintf("Unexpected policy requirement type \"%s\"", tmp.Type))
}
if signedIdentity == nil {
tmp.SignedIdentity = NewPRMMatchExact()
tmp.SignedIdentity = NewPRMMatchExact(true)
} else {
si, err := newPolicyReferenceMatchFromJSON(signedIdentity)
if err != nil {
Expand Down Expand Up @@ -501,7 +501,7 @@ func (pr *prSignedBaseLayer) UnmarshalJSON(data []byte) error {
return nil
}

// newPolicyRequirementFromJSON parses JSON data into a PolicyReferenceMatch implementation.
// newPolicyReferenceFromJSON parses JSON data into a PolicyReferenceMatch implementation.
func newPolicyReferenceMatchFromJSON(data []byte) (PolicyReferenceMatch, error) {
var typeField prmCommon
if err := json.Unmarshal(data, &typeField); err != nil {
Expand All @@ -527,13 +527,16 @@ func newPolicyReferenceMatchFromJSON(data []byte) (PolicyReferenceMatch, error)
}

// newPRMMatchExact is NewPRMMatchExact, except it resturns the private type.
func newPRMMatchExact() *prmMatchExact {
return &prmMatchExact{prmCommon{Type: prmTypeMatchExact}}
func newPRMMatchExact(allowReferencesByDigest bool) *prmMatchExact {
return &prmMatchExact{
prmCommon: prmCommon{Type: prmTypeMatchExact},
AllowReferencesByDigest: allowReferencesByDigest,
}
}

// NewPRMMatchExact returns a new "matchExact" PolicyReferenceMatch.
func NewPRMMatchExact() PolicyReferenceMatch {
return newPRMMatchExact()
func NewPRMMatchExact(allowReferencesByDigest bool) PolicyReferenceMatch {
return newPRMMatchExact(allowReferencesByDigest)
}

// Compile-time check that prmMatchExact implements json.Unmarshaler.
Expand All @@ -542,11 +545,13 @@ var _ json.Unmarshaler = (*prmMatchExact)(nil)
// UnmarshalJSON implements the json.Unmarshaler interface.
func (prm *prmMatchExact) UnmarshalJSON(data []byte) error {
*prm = prmMatchExact{}
var tmp prmMatchExact
tmp := prmMatchExact{AllowReferencesByDigest: true} // NOTE: The JSON default is different from the Golang default
if err := paranoidUnmarshalJSONObject(data, func(key string) interface{} {
switch key {
case "type":
return &tmp.Type
case "allowReferencesByDigest":
return &tmp.AllowReferencesByDigest
default:
return nil
}
Expand All @@ -557,7 +562,7 @@ func (prm *prmMatchExact) UnmarshalJSON(data []byte) error {
if tmp.Type != prmTypeMatchExact {
return InvalidPolicyFormatError(fmt.Sprintf("Unexpected policy requirement type \"%s\"", tmp.Type))
}
*prm = *newPRMMatchExact()
*prm = *newPRMMatchExact(tmp.AllowReferencesByDigest)
return nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,23 @@ func (prm *prmMatchExact) matchesDockerReference(image types.UnparsedImage, sign
if err != nil {
return false
}

// Do not add default tags: image.Reference().DockerReference() should contain it already, and signatureDockerReference should be exact; so, verify that now.
if reference.IsNameOnly(intended) || reference.IsNameOnly(signature) {
if reference.IsNameOnly(signature) {
return false
}
switch intended.(type) {
case reference.NamedTagged: // Includes the case when intended has both a tag and a digest.
return signature.String() == intended.String()
case reference.Canonical:
// We don’t actually compare the manifest digest against the signature here; that happens prSignedBy.in UnparsedImage.Manifest.
// Becase UnparsedImage.Manifest verifies the intended.Digest() against the manifest, and prSignedBy verifies the signature digest against the manifest,
// we know that signature digest matches intended.Digest() (but intended.Digest() and signature digest may use different algorithms)
// FIXME? Compare the digests here anyway, for extra safety against code changes, at the cost of not supporting pull-by-digest using a different algorithm than the signature?
return prm.AllowReferencesByDigest
default: // !reference.IsNameOnly(intended)
return false
}
return signature.String() == intended.String()
}

func (prm *prmMatchRepository) matchesDockerReference(image types.UnparsedImage, signatureDockerReference string) bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,11 @@ const (
prmTypeExactRepository prmTypeIdentifier = "exactRepository"
)

// prmMatchExact is a PolicyReferenceMatch with type = prmMatchExact: the two references must match exactly.
// prmMatchExact is a PolicyReferenceMatch with type = prmMatchExact: the two references must match exactly,
// except that digest references may be accepted regardless of tag if AllowReferencesByDigest
type prmMatchExact struct {
prmCommon
AllowReferencesByDigest bool `json:"allowReferencesByDigest"` // NOTE: If missing in JSON, this defaults to true (but defaults to false in Golang!)
}

// prmMatchRepository is a PolicyReferenceMatch with type = prmMatchRepository: the two references must use the same repository, may differ in the tag.
Expand Down