Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proxy: Policy verification of OCI Image before pulling #2029

Merged
merged 1 commit into from
Jul 4, 2023
Merged
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
21 changes: 20 additions & 1 deletion cmd/skopeo/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import (
"github.com/containers/image/v5/manifest"
ocilayout "github.com/containers/image/v5/oci/layout"
"github.com/containers/image/v5/pkg/blobinfocache"
"github.com/containers/image/v5/signature"
"github.com/containers/image/v5/transports"
"github.com/containers/image/v5/transports/alltransports"
"github.com/containers/image/v5/types"
Expand All @@ -95,7 +96,8 @@ import (
// 0.2.3: Added GetFullConfig
// 0.2.4: Added OpenImageOptional
// 0.2.5: Added LayerInfoJSON
const protocolVersion = "0.2.5"
// 0.2.6: Policy Verification before pulling OCI
const protocolVersion = "0.2.6"

// maxMsgSize is the current limit on a packet size.
// Note that all non-metadata (i.e. payload data) is sent over a pipe.
Expand Down Expand Up @@ -266,6 +268,23 @@ func (h *proxyHandler) openImageImpl(args []any, allowNotFound bool) (replyBuf,
return ret, err
}

unparsedTopLevel := image.UnparsedInstance(imgsrc, nil)
policy, err := signature.DefaultPolicy(h.sysctx)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I think this is OK for now, maybe it makes sense to cache this in the future?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, cache the PolicyContext (as long as it is used from a single thread).

(Right now that does not make a difference, but a branch caching the imported keys in a native format inside a PolicyContext is floating around.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there a specific reason not to use opts.global.getPolicyContext here?

That would also immediately handle --insecure-policy per #2029 (review) .

if err != nil {
return ret, err
}
policyContext, err := signature.NewPolicyContext(policy)
if err != nil {
return ret, err
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

policyContext.Destroy is required by the API when done.

allowed, err := policyContext.IsRunningImageAllowed(context.Background(), unparsedTopLevel)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here'd what we want is a new API like IsRunningImageSigned and it would fail if the signature policy is insecureAcceptAnything for ostreedev/ostree-rs-ext#79

if !allowed || err != nil {
return ret, err
RishabhSaini marked this conversation as resolved.
Show resolved Hide resolved
}
if !allowed && err == nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is dead code AFAICS. The code has already returned ret, nil above.

return ret, fmt.Errorf("policy verification failed unexpectedly")
}

// Note that we never return zero as an imageid; this code doesn't yet
// handle overflow though.
h.imageSerial++
Expand Down