diff --git a/signature/policy_config.go b/signature/policy_config.go index 1f74e19d99..20821a3509 100644 --- a/signature/policy_config.go +++ b/signature/policy_config.go @@ -24,6 +24,15 @@ import ( "github.com/docker/docker/reference" ) +// systemDefaultPolicyPath is the policy path used for DefaultPolicy(). +// You can override this at build time with +// -ldflags '-X github.com/containers/image/signature.systemDefaultPolicyPath=$your_path' +var systemDefaultPolicyPath = builtinDefaultPolicyPath + +// builtinDefaultPolicyPath is the policy pat used for DefaultPolicy(). +// DO NOT change this, instead see systemDefaultPolicyPath above. +const builtinDefaultPolicyPath = "/etc/containers/policy.json" + // InvalidPolicyFormatError is returned when parsing an invalid policy configuration. type InvalidPolicyFormatError string @@ -33,6 +42,24 @@ func (err InvalidPolicyFormatError) Error() string { // FIXME: NewDefaultPolicy, from default file (or environment if trusted?) +// DefaultPolicy returns the default policy of the system. +// Most applications should be using this method to get the policy configured +// by the system administrator. +// ctx should usually be nil, can be set to override the default. +// NOTE: When this function returns an error, report it to the user and abort. +// DO NOT hard-code fallback policies in your application. +func DefaultPolicy(ctx *types.SystemContext) (*Policy, error) { + return NewPolicyFromFile(defaultPolicyPath(ctx)) +} + +// defaultPolicyPath returns a path to the default policy of the system. +func defaultPolicyPath(ctx *types.SystemContext) string { + if ctx != nil && ctx.SignaturePolicyPath != "" { + return ctx.SignaturePolicyPath + } + return systemDefaultPolicyPath +} + // NewPolicyFromFile returns a policy configured in the specified file. func NewPolicyFromFile(fileName string) (*Policy, error) { contents, err := ioutil.ReadFile(fileName) diff --git a/signature/policy_config_test.go b/signature/policy_config_test.go index 6062ce1839..7a0c15777d 100644 --- a/signature/policy_config_test.go +++ b/signature/policy_config_test.go @@ -63,6 +63,40 @@ var policyFixtureContents = &Policy{ }, } +func TestDefaultPolicy(t *testing.T) { + // We can't test the actual systemDefaultPolicyPath, so override. + // TestDefaultPolicyPath below tests that we handle the overrides and defaults + // correctly. + + // Success + policy, err := DefaultPolicy(&types.SystemContext{SignaturePolicyPath: "./fixtures/policy.json"}) + require.NoError(t, err) + assert.Equal(t, policyFixtureContents, policy) + + for _, path := range []string{ + "/this/doesnt/exist", // Error reading file + "/dev/null", // A failure case; most are tested in the individual method unit tests. + } { + policy, err := DefaultPolicy(&types.SystemContext{SignaturePolicyPath: path}) + assert.Error(t, err) + assert.Nil(t, policy) + } +} + +func TestDefaultPolicyPath(t *testing.T) { + // The common case + path := defaultPolicyPath(nil) + assert.Equal(t, systemDefaultPolicyPath, path) + // There is a context, but it does not override the path. + path = defaultPolicyPath(&types.SystemContext{}) + assert.Equal(t, systemDefaultPolicyPath, path) + + // Path overridden + const nondefaultPath = "/this/is/not/the/default/path.json" + path = defaultPolicyPath(&types.SystemContext{SignaturePolicyPath: nondefaultPath}) + assert.Equal(t, nondefaultPath, path) +} + func TestNewPolicyFromFile(t *testing.T) { // Success policy, err := NewPolicyFromFile("./fixtures/policy.json") diff --git a/types/types.go b/types/types.go index b67e6b3012..c5eb5ab65b 100644 --- a/types/types.go +++ b/types/types.go @@ -147,3 +147,12 @@ type ImageInspectInfo struct { Os string Layers []string } + +// SystemContext allows parametrizing access to implicitly-accessed resources, +// like configuration files in /etc and users' login state in their home directory. +// Various components can share the same field only if their semantics is exactly +// the same; if in doubt, add a new field. +// It is always OK to pass nil instead of a SystemContext. +type SystemContext struct { + SignaturePolicyPath string // If not "", overrides the system's default path for signature.Policy configuration. +}