From a02aa8f6a295f0572735a53b8e984184aaf4e66a Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Tue, 20 Feb 2024 14:47:22 +0100 Subject: [PATCH] pkg/machine/ocipull: add custom policy.json location The default policy file /etc/containers/policy.json location does not work on windows and for packages that ship a default. Now we search for the policy.json in the following overwrite locations: macos and linux: - ~/.config/containers/policy.json - /etc/containers/policy.json windows: - %APPDATA%\containers\policy.json Also it offers an additional DefaultPolicyJSONPath var that should be overwritten at built time with the path of the file that is shipped by packagers. Thile file is used when none of the overwrite paths exist. [NO NEW TESTS NEEDED] Signed-off-by: Paul Holzinger --- pkg/machine/ocipull/policy.go | 47 +++++++++++++++++++++++++++ pkg/machine/ocipull/policy_unix.go | 19 +++++++++++ pkg/machine/ocipull/policy_windows.go | 10 ++++++ pkg/machine/ocipull/pull.go | 9 +++-- 4 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 pkg/machine/ocipull/policy.go create mode 100644 pkg/machine/ocipull/policy_unix.go create mode 100644 pkg/machine/ocipull/policy_windows.go diff --git a/pkg/machine/ocipull/policy.go b/pkg/machine/ocipull/policy.go new file mode 100644 index 0000000000..aab3b81dda --- /dev/null +++ b/pkg/machine/ocipull/policy.go @@ -0,0 +1,47 @@ +package ocipull + +import ( + "fmt" + "os" + "path/filepath" +) + +// DefaultPolicyJSONPath should be overwritten at build time with the real path to the directory where +// the shipped policy.json file is located. This can either be absolute path or a relative path. If it +// is relative it will be resolved relative to the podman binary and NOT the CWD. +// +// use "-X github.com/containers/podman/v5/pkg/machine/ocipull.DefaultPolicyJSONPath=/somepath" in go ldflags to overwrite this +var DefaultPolicyJSONPath = "" + +const policyfile = "policy.json" + +type defaultPolicyError struct { + errs []error +} + +func (e *defaultPolicyError) Error() string { + return fmt.Sprintf("no DefaultPolicyJSONPath defined and no local overwrites found: %q", e.errs) +} + +func policyPath() (string, error) { + paths := localPolicyOverwrites() + errs := make([]error, 0, len(paths)) + for _, path := range paths { + _, err := os.Stat(path) + if err == nil { + return path, nil + } + errs = append(errs, err) + } + if DefaultPolicyJSONPath != "" { + if filepath.IsAbs(DefaultPolicyJSONPath) { + return filepath.Join(DefaultPolicyJSONPath, policyfile), nil + } + p, err := os.Executable() + if err != nil { + return "", fmt.Errorf("could not resolve relative path to binary: %w", err) + } + return filepath.Join(p, DefaultPolicyJSONPath, policyfile), nil + } + return "", &defaultPolicyError{errs: errs} +} diff --git a/pkg/machine/ocipull/policy_unix.go b/pkg/machine/ocipull/policy_unix.go new file mode 100644 index 0000000000..2fd0443583 --- /dev/null +++ b/pkg/machine/ocipull/policy_unix.go @@ -0,0 +1,19 @@ +//go:build !windows + +package ocipull + +import ( + "path/filepath" + + "github.com/containers/common/pkg/config" + "github.com/containers/storage/pkg/homedir" +) + +func localPolicyOverwrites() []string { + var dirs []string + if p, err := homedir.GetConfigHome(); err == nil { + dirs = append(dirs, filepath.Join(p, "containers", policyfile)) + } + dirs = append(dirs, config.DefaultSignaturePolicyPath) + return dirs +} diff --git a/pkg/machine/ocipull/policy_windows.go b/pkg/machine/ocipull/policy_windows.go new file mode 100644 index 0000000000..3a1c31932c --- /dev/null +++ b/pkg/machine/ocipull/policy_windows.go @@ -0,0 +1,10 @@ +package ocipull + +import ( + "os" + "path/filepath" +) + +func localPolicyOverwrites() []string { + return []string{filepath.Join(os.Getenv("APPDATA"), "containers", policyfile)} +} diff --git a/pkg/machine/ocipull/pull.go b/pkg/machine/ocipull/pull.go index e484964da7..dce8147d9d 100644 --- a/pkg/machine/ocipull/pull.go +++ b/pkg/machine/ocipull/pull.go @@ -44,9 +44,14 @@ func Pull(ctx context.Context, imageInput types.ImageReference, localDestPath *d sysCtx.DockerAuthConfig = authConf } - policy, err := signature.DefaultPolicy(sysCtx) + path, err := policyPath() if err != nil { - return fmt.Errorf("obtaining default signature policy: %w", err) + return err + } + + policy, err := signature.NewPolicyFromFile(path) + if err != nil { + return fmt.Errorf("obtaining signature policy: %w", err) } policyContext, err := signature.NewPolicyContext(policy) if err != nil {