Skip to content

Commit

Permalink
Merge pull request #7081 from QiWang19/sigature-store
Browse files Browse the repository at this point in the history
fix bug podman sign storage path
  • Loading branch information
openshift-merge-robot authored Aug 5, 2020
2 parents ca2ecce + 69ac054 commit 0a3f3c9
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 40 deletions.
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ require (
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299
gopkg.in/yaml.v2 v2.3.0
k8s.io/api v0.18.6
k8s.io/apimachinery v0.18.6
k8s.io/client-go v0.0.0-20190620085101-78d2af792bab
Expand Down
65 changes: 28 additions & 37 deletions pkg/domain/infra/abi/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io/ioutil"
"net/url"
"os"
"path"
"path/filepath"
"strconv"
"strings"
Expand Down Expand Up @@ -682,10 +683,6 @@ func (ir *ImageEngine) Shutdown(_ context.Context) {
}

func (ir *ImageEngine) Sign(ctx context.Context, names []string, options entities.SignOptions) (*entities.SignReport, error) {
dockerRegistryOptions := image.DockerRegistryOptions{
DockerCertPath: options.CertDir,
}

mech, err := signature.NewGPGSigningMechanism()
if err != nil {
return nil, errors.Wrap(err, "error initializing GPG")
Expand All @@ -704,7 +701,6 @@ func (ir *ImageEngine) Sign(ctx context.Context, names []string, options entitie
}

for _, signimage := range names {
var sigStoreDir string
srcRef, err := alltransports.ParseImageName(signimage)
if err != nil {
return nil, errors.Wrapf(err, "error parsing image name")
Expand All @@ -725,63 +721,60 @@ func (ir *ImageEngine) Sign(ctx context.Context, names []string, options entitie
if dockerReference == nil {
return nil, errors.Errorf("cannot determine canonical Docker reference for destination %s", transports.ImageName(rawSource.Reference()))
}

// create the signstore file
rtc, err := ir.Libpod.GetConfig()
if err != nil {
return nil, err
}
newImage, err := ir.Libpod.ImageRuntime().New(ctx, signimage, rtc.Engine.SignaturePolicyPath, "", os.Stderr, &dockerRegistryOptions, image.SigningOptions{SignBy: options.SignBy}, nil, util.PullImageMissing)
if err != nil {
return nil, errors.Wrapf(err, "error pulling image %s", signimage)
var sigStoreDir string
if options.Directory != "" {
sigStoreDir = options.Directory
}
if sigStoreDir == "" {
if rootless.IsRootless() {
sigStoreDir = filepath.Join(filepath.Dir(ir.Libpod.StorageConfig().GraphRoot), "sigstore")
} else {
var sigStoreURI string
registryInfo := trust.HaveMatchRegistry(rawSource.Reference().DockerReference().String(), registryConfigs)
if registryInfo != nil {
if sigStoreDir = registryInfo.SigStoreStaging; sigStoreDir == "" {
sigStoreDir = registryInfo.SigStore

if sigStoreURI = registryInfo.SigStoreStaging; sigStoreURI == "" {
sigStoreURI = registryInfo.SigStore
}
}
if sigStoreURI == "" {
return nil, errors.Errorf("no signature storage configuration found for %s", rawSource.Reference().DockerReference().String())

}
sigStoreDir, err = localPathFromURI(sigStoreURI)
if err != nil {
return nil, errors.Wrapf(err, "invalid signature storage %s", sigStoreURI)
}
}
}
sigStoreDir, err = isValidSigStoreDir(sigStoreDir)
manifestDigest, err := manifest.Digest(getManifest)
if err != nil {
return nil, errors.Wrapf(err, "invalid signature storage %s", sigStoreDir)
}
repos, err := newImage.RepoDigests()
if err != nil {
return nil, errors.Wrapf(err, "error calculating repo digests for %s", signimage)
return nil, err
}
if len(repos) == 0 {
logrus.Errorf("no repodigests associated with the image %s", signimage)
continue
repo := reference.Path(dockerReference)
if path.Clean(repo) != repo { // Coverage: This should not be reachable because /./ and /../ components are not valid in docker references
return nil, errors.Errorf("Unexpected path elements in Docker reference %s for signature storage", dockerReference.String())
}

// create signature
newSig, err := signature.SignDockerManifest(getManifest, dockerReference.String(), mech, options.SignBy)
if err != nil {
return nil, errors.Wrapf(err, "error creating new signature")
}

trimmedDigest := strings.TrimPrefix(repos[0], strings.Split(repos[0], "/")[0])
sigStoreDir = filepath.Join(sigStoreDir, strings.Replace(trimmedDigest, ":", "=", 1))
if err := os.MkdirAll(sigStoreDir, 0751); err != nil {
// create the signstore file
signatureDir := fmt.Sprintf("%s@%s=%s", filepath.Join(sigStoreDir, repo), manifestDigest.Algorithm(), manifestDigest.Hex())
if err := os.MkdirAll(signatureDir, 0751); err != nil {
// The directory is allowed to exist
if !os.IsExist(err) {
logrus.Errorf("error creating directory %s: %s", sigStoreDir, err)
logrus.Errorf("error creating directory %s: %s", signatureDir, err)
continue
}
}
sigFilename, err := getSigFilename(sigStoreDir)
sigFilename, err := getSigFilename(signatureDir)
if err != nil {
logrus.Errorf("error creating sigstore file: %v", err)
continue
}
err = ioutil.WriteFile(filepath.Join(sigStoreDir, sigFilename), newSig, 0644)
err = ioutil.WriteFile(filepath.Join(signatureDir, sigFilename), newSig, 0644)
if err != nil {
logrus.Errorf("error storing signature for %s", rawSource.Reference().DockerReference().String())
continue
Expand Down Expand Up @@ -809,14 +802,12 @@ func getSigFilename(sigStoreDirPath string) (string, error) {
}
}

func isValidSigStoreDir(sigStoreDir string) (string, error) {
writeURIs := map[string]bool{"file": true}
func localPathFromURI(sigStoreDir string) (string, error) {
url, err := url.Parse(sigStoreDir)
if err != nil {
return sigStoreDir, errors.Wrapf(err, "invalid directory %s", sigStoreDir)
}
_, exists := writeURIs[url.Scheme]
if !exists {
if url.Scheme != "file" {
return sigStoreDir, errors.Errorf("writing to %s is not supported. Use a supported scheme", sigStoreDir)
}
sigStoreDir = url.Path
Expand Down
4 changes: 2 additions & 2 deletions pkg/trust/trust.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (
"strings"

"github.com/containers/image/v5/types"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
)

// PolicyContent struct for policy.json file
Expand Down Expand Up @@ -157,7 +157,7 @@ func HaveMatchRegistry(key string, registryConfigs *RegistryConfiguration) *Regi
searchKey = searchKey[:strings.LastIndex(searchKey, "/")]
}
}
return nil
return registryConfigs.DefaultDocker
}

// CreateTmpFile creates a temp file under dir and writes the content into it
Expand Down
62 changes: 62 additions & 0 deletions test/e2e/image_sign_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// +build !remote

package integration

import (
"os"
"os/exec"
"path/filepath"

. "github.com/containers/podman/v2/test/utils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("Podman image sign", func() {
var (
origGNUPGHOME string
tempdir string
err error
podmanTest *PodmanTestIntegration
)

BeforeEach(func() {
tempdir, err = CreateTempDirInTempDir()
if err != nil {
os.Exit(1)
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
podmanTest.SeedImages()

tempGNUPGHOME := filepath.Join(podmanTest.TempDir, "tmpGPG")
err := os.Mkdir(tempGNUPGHOME, os.ModePerm)
Expect(err).To(BeNil())

origGNUPGHOME = os.Getenv("GNUPGHOME")
err = os.Setenv("GNUPGHOME", tempGNUPGHOME)
Expect(err).To(BeNil())

})

AfterEach(func() {
podmanTest.Cleanup()
f := CurrentGinkgoTestDescription()
processTestResult(f)
os.Setenv("GNUPGHOME", origGNUPGHOME)
})

It("podman sign image", func() {
cmd := exec.Command("gpg", "--import", "sign/secret-key.asc")
err := cmd.Run()
Expect(err).To(BeNil())
sigDir := filepath.Join(podmanTest.TempDir, "test-sign")
err = os.MkdirAll(sigDir, os.ModePerm)
Expect(err).To(BeNil())
session := podmanTest.Podman([]string{"image", "sign", "--directory", sigDir, "--sign-by", "[email protected]", "docker://library/alpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
_, err = os.Stat(filepath.Join(sigDir, "library"))
Expect(err).To(BeNil())
})
})
57 changes: 57 additions & 0 deletions test/e2e/sign/secret-key.asc
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----

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
=6kcB
-----END PGP PRIVATE KEY BLOCK-----

0 comments on commit 0a3f3c9

Please sign in to comment.