Fix up image sign in PR 2108

Signed-off-by: Qi Wang <qiwan@redhat.com>
This commit is contained in:
Qi Wang
2019-01-11 11:38:44 -05:00
parent 264d082106
commit e24167eef9
2 changed files with 153 additions and 121 deletions

View File

@ -6,6 +6,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"sort" "sort"
"strings"
"github.com/containers/image/types" "github.com/containers/image/types"
"github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/cmd/podman/formats"
@ -13,6 +14,7 @@ import (
"github.com/containers/libpod/libpod/image" "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/trust" "github.com/containers/libpod/pkg/trust"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -103,6 +105,7 @@ func showTrustCmd(c *cli.Context) error {
var ( var (
policyPath string policyPath string
systemRegistriesDirPath string systemRegistriesDirPath string
outjson interface{}
) )
if c.IsSet("policypath") { if c.IsSet("policypath") {
policyPath = c.String("policypath") policyPath = c.String("policypath")
@ -127,30 +130,26 @@ func showTrustCmd(c *cli.Context) error {
return nil return nil
} }
var policyContentStruct trust.PolicyContent policyContentStruct, err := trust.GetPolicy(policyPath)
if err := json.Unmarshal(policyContent, &policyContentStruct); err != nil {
return errors.Errorf("could not read trust policies")
}
policyJSON, showOutputMap, err := trust.GetPolicy(policyContentStruct, systemRegistriesDirPath)
if err != nil { if err != nil {
return errors.Wrapf(err, "error reading registry config file") return errors.Wrapf(err, "could not read trust policies")
} }
if c.Bool("json") { if c.Bool("json") {
var outjson interface{} policyJSON, err := getPolicyJSON(policyContentStruct, systemRegistriesDirPath)
if err != nil {
return errors.Wrapf(err, "could not show trust policies in JSON format")
}
outjson = policyJSON outjson = policyJSON
out := formats.JSONStruct{Output: outjson} out := formats.JSONStruct{Output: outjson}
return formats.Writer(out).Out() return formats.Writer(out).Out()
} }
sortedRepos := sortPolicyJSONKey(policyJSON) showOutputMap, err := getPolicyShowOutput(policyContentStruct, systemRegistriesDirPath)
var output []interface{} if err != nil {
for _, reponame := range sortedRepos { return errors.Wrapf(err, "could not show trust policies")
showOutput, exists := showOutputMap[reponame]
if exists {
output = append(output, interface{}(showOutput))
}
} }
out := formats.StdoutTemplateArray{Output: output, Template: "{{.Repo}}\t{{.Trusttype}}\t{{.GPGid}}\t{{.Sigstore}}"} out := formats.StdoutTemplateArray{Output: showOutputMap, Template: "{{.Repo}}\t{{.Trusttype}}\t{{.GPGid}}\t{{.Sigstore}}"}
return formats.Writer(out).Out() return formats.Writer(out).Out()
} }
@ -159,7 +158,11 @@ func setTrustCmd(c *cli.Context) error {
if err != nil { if err != nil {
return errors.Wrapf(err, "could not create runtime") return errors.Wrapf(err, "could not create runtime")
} }
var (
policyPath string
policyContentStruct trust.PolicyContent
newReposContent []trust.RepoContent
)
args := c.Args() args := c.Args()
if len(args) != 1 { if len(args) != 1 {
return errors.Errorf("default or a registry name must be specified") return errors.Errorf("default or a registry name must be specified")
@ -182,17 +185,13 @@ func setTrustCmd(c *cli.Context) error {
return errors.Errorf("At least one public key must be defined for type 'signedBy'") return errors.Errorf("At least one public key must be defined for type 'signedBy'")
} }
var policyPath string
if c.IsSet("policypath") { if c.IsSet("policypath") {
policyPath = c.String("policypath") policyPath = c.String("policypath")
} else { } else {
policyPath = trust.DefaultPolicyPath(runtime.SystemContext()) policyPath = trust.DefaultPolicyPath(runtime.SystemContext())
} }
var policyContentStruct trust.PolicyContent
policyFileExists := false
_, err = os.Stat(policyPath) _, err = os.Stat(policyPath)
if !os.IsNotExist(err) { if !os.IsNotExist(err) {
policyFileExists = true
policyContent, err := ioutil.ReadFile(policyPath) policyContent, err := ioutil.ReadFile(policyPath)
if err != nil { if err != nil {
return errors.Wrapf(err, "unable to read %s", policyPath) return errors.Wrapf(err, "unable to read %s", policyPath)
@ -200,11 +199,7 @@ func setTrustCmd(c *cli.Context) error {
if err := json.Unmarshal(policyContent, &policyContentStruct); err != nil { if err := json.Unmarshal(policyContent, &policyContentStruct); err != nil {
return errors.Errorf("could not read trust policies") return errors.Errorf("could not read trust policies")
} }
if args[0] != "default" && len(policyContentStruct.Default) == 0 {
return errors.Errorf("Default trust policy must be set.")
}
} }
var newReposContent []trust.RepoContent
if len(pubkeysfile) != 0 { if len(pubkeysfile) != 0 {
for _, filepath := range pubkeysfile { for _, filepath := range pubkeysfile {
newReposContent = append(newReposContent, trust.RepoContent{Type: trusttype, KeyType: "GPGKeys", KeyPath: filepath}) newReposContent = append(newReposContent, trust.RepoContent{Type: trusttype, KeyType: "GPGKeys", KeyPath: filepath})
@ -215,8 +210,8 @@ func setTrustCmd(c *cli.Context) error {
if args[0] == "default" { if args[0] == "default" {
policyContentStruct.Default = newReposContent policyContentStruct.Default = newReposContent
} else { } else {
if policyFileExists == false && len(policyContentStruct.Default) == 0 { if len(policyContentStruct.Default) == 0 {
return errors.Errorf("Default trust policy must be set to create the policy file.") return errors.Errorf("Default trust policy must be set.")
} }
registryExists := false registryExists := false
for transport, transportval := range policyContentStruct.Transports { for transport, transportval := range policyContentStruct.Transports {
@ -248,7 +243,7 @@ func setTrustCmd(c *cli.Context) error {
return nil return nil
} }
func sortPolicyJSONKey(m map[string]map[string]interface{}) []string { func sortShowOutputMapKey(m map[string]trust.ShowOutput) []string {
keys := make([]string, len(m)) keys := make([]string, len(m))
i := 0 i := 0
for k := range m { for k := range m {
@ -269,3 +264,106 @@ func isValidTrustType(t string) bool {
func getDefaultPolicyPath() string { func getDefaultPolicyPath() string {
return trust.DefaultPolicyPath(&types.SystemContext{}) return trust.DefaultPolicyPath(&types.SystemContext{})
} }
func getPolicyJSON(policyContentStruct trust.PolicyContent, systemRegistriesDirPath string) (map[string]map[string]interface{}, error) {
registryConfigs, err := trust.LoadAndMergeConfig(systemRegistriesDirPath)
if err != nil {
return nil, err
}
policyJSON := make(map[string]map[string]interface{})
if len(policyContentStruct.Default) > 0 {
policyJSON["* (default)"] = make(map[string]interface{})
policyJSON["* (default)"]["type"] = policyContentStruct.Default[0].Type
}
for transname, transval := range policyContentStruct.Transports {
for repo, repoval := range transval {
policyJSON[repo] = make(map[string]interface{})
policyJSON[repo]["type"] = repoval[0].Type
policyJSON[repo]["transport"] = transname
keyarr := []string{}
uids := []string{}
for _, repoele := range repoval {
if len(repoele.KeyPath) > 0 {
keyarr = append(keyarr, repoele.KeyPath)
uids = append(uids, trust.GetGPGIdFromKeyPath(repoele.KeyPath)...)
}
if len(repoele.KeyData) > 0 {
keyarr = append(keyarr, string(repoele.KeyData))
uids = append(uids, trust.GetGPGIdFromKeyData(string(repoele.KeyData))...)
}
}
policyJSON[repo]["keys"] = keyarr
policyJSON[repo]["sigstore"] = ""
registryNamespace := trust.HaveMatchRegistry(repo, registryConfigs)
if registryNamespace != nil {
policyJSON[repo]["sigstore"] = registryNamespace.SigStore
}
}
}
return policyJSON, nil
}
var typeDescription = map[string]string{"insecureAcceptAnything": "accept", "signedBy": "signed", "reject": "reject"}
func trustTypeDescription(trustType string) string {
trustDescription, exist := typeDescription[trustType]
if !exist {
logrus.Warnf("invalid trust type %s", trustType)
}
return trustDescription
}
func getPolicyShowOutput(policyContentStruct trust.PolicyContent, systemRegistriesDirPath string) ([]interface{}, error) {
var output []interface{}
registryConfigs, err := trust.LoadAndMergeConfig(systemRegistriesDirPath)
if err != nil {
return nil, err
}
trustShowOutputMap := make(map[string]trust.ShowOutput)
if len(policyContentStruct.Default) > 0 {
defaultPolicyStruct := trust.ShowOutput{
Repo: "default",
Trusttype: trustTypeDescription(policyContentStruct.Default[0].Type),
}
trustShowOutputMap["* (default)"] = defaultPolicyStruct
}
for _, transval := range policyContentStruct.Transports {
for repo, repoval := range transval {
tempTrustShowOutput := trust.ShowOutput{
Repo: repo,
Trusttype: repoval[0].Type,
}
keyarr := []string{}
uids := []string{}
for _, repoele := range repoval {
if len(repoele.KeyPath) > 0 {
keyarr = append(keyarr, repoele.KeyPath)
uids = append(uids, trust.GetGPGIdFromKeyPath(repoele.KeyPath)...)
}
if len(repoele.KeyData) > 0 {
keyarr = append(keyarr, string(repoele.KeyData))
uids = append(uids, trust.GetGPGIdFromKeyData(string(repoele.KeyData))...)
}
}
tempTrustShowOutput.GPGid = strings.Join(uids, ", ")
registryNamespace := trust.HaveMatchRegistry(repo, registryConfigs)
if registryNamespace != nil {
tempTrustShowOutput.Sigstore = registryNamespace.SigStore
}
trustShowOutputMap[repo] = tempTrustShowOutput
}
}
sortedRepos := sortShowOutputMapKey(trustShowOutputMap)
for _, reponame := range sortedRepos {
showOutput, exists := trustShowOutputMap[reponame]
if exists {
output = append(output, interface{}(showOutput))
}
}
return output, nil
}

View File

@ -175,43 +175,30 @@ func CreateTmpFile(dir, pattern string, content []byte) (string, error) {
return tmpfile.Name(), nil return tmpfile.Name(), nil
} }
func getGPGIdFromKeyPath(path []string) []string { // GetGPGIdFromKeyPath return user keyring from key path
var uids []string func GetGPGIdFromKeyPath(path string) []string {
for _, k := range path { cmd := exec.Command("gpg2", "--with-colons", path)
cmd := exec.Command("gpg2", "--with-colons", k) results, err := cmd.Output()
results, err := cmd.Output() if err != nil {
if err != nil { logrus.Errorf("error getting key identity: %s", err)
logrus.Warnf("error get key identity: %s", err) return nil
continue
}
uids = append(uids, parseUids(results)...)
} }
return uids return parseUids(results)
} }
func getGPGIdFromKeyData(keys []string) []string { // GetGPGIdFromKeyData return user keyring from keydata
var uids []string func GetGPGIdFromKeyData(key string) []string {
for _, k := range keys { decodeKey, err := base64.StdEncoding.DecodeString(key)
decodeKey, err := base64.StdEncoding.DecodeString(k) if err != nil {
if err != nil { logrus.Errorf("%s, error decoding key data", err)
logrus.Warnf("error decoding key data") return nil
continue
}
tmpfileName, err := CreateTmpFile("", "", decodeKey)
if err != nil {
logrus.Warnf("error creating key date temp file %s", err)
}
defer os.Remove(tmpfileName)
k = tmpfileName
cmd := exec.Command("gpg2", "--with-colons", k)
results, err := cmd.Output()
if err != nil {
logrus.Warnf("error get key identity: %s", err)
continue
}
uids = append(uids, parseUids(results)...)
} }
return uids tmpfileName, err := CreateTmpFile("", "", decodeKey)
if err != nil {
logrus.Errorf("error creating key date temp file %s", err)
}
defer os.Remove(tmpfileName)
return GetGPGIdFromKeyPath(tmpfileName)
} }
func parseUids(colonDelimitKeys []byte) []string { func parseUids(colonDelimitKeys []byte) []string {
@ -234,68 +221,15 @@ func parseUids(colonDelimitKeys []byte) []string {
return parseduids return parseduids
} }
var typeDescription = map[string]string{"insecureAcceptAnything": "accept", "signedBy": "signed", "reject": "reject"} // GetPolicy parse policy.json into PolicyContent struct
func GetPolicy(policyPath string) (PolicyContent, error) {
func trustTypeDescription(trustType string) string { var policyContentStruct PolicyContent
trustDescription, exist := typeDescription[trustType] policyContent, err := ioutil.ReadFile(policyPath)
if !exist {
logrus.Warnf("invalid trust type %s", trustType)
}
return trustDescription
}
// GetPolicy return the struct to show policy.json in json format and a map (reponame, ShowOutput) pair for image trust show command
func GetPolicy(policyContentStruct PolicyContent, systemRegistriesDirPath string) (map[string]map[string]interface{}, map[string]ShowOutput, error) {
registryConfigs, err := LoadAndMergeConfig(systemRegistriesDirPath)
if err != nil { if err != nil {
return nil, nil, err return policyContentStruct, errors.Wrapf(err, "unable to read policy file %s", policyPath)
} }
if err := json.Unmarshal(policyContent, &policyContentStruct); err != nil {
trustShowOutputMap := make(map[string]ShowOutput) return policyContentStruct, errors.Wrapf(err, "could not parse trust policies")
policyJSON := make(map[string]map[string]interface{})
if len(policyContentStruct.Default) > 0 {
policyJSON["* (default)"] = make(map[string]interface{})
policyJSON["* (default)"]["type"] = policyContentStruct.Default[0].Type
var defaultPolicyStruct ShowOutput
defaultPolicyStruct.Repo = "default"
defaultPolicyStruct.Trusttype = trustTypeDescription(policyContentStruct.Default[0].Type)
trustShowOutputMap["* (default)"] = defaultPolicyStruct
} }
for transname, transval := range policyContentStruct.Transports { return policyContentStruct, nil
for repo, repoval := range transval {
tempTrustShowOutput := ShowOutput{
Repo: repo,
Trusttype: repoval[0].Type,
}
policyJSON[repo] = make(map[string]interface{})
policyJSON[repo]["type"] = repoval[0].Type
policyJSON[repo]["transport"] = transname
keyDataArr := []string{}
keyPathArr := []string{}
keyarr := []string{}
for _, repoele := range repoval {
if len(repoele.KeyPath) > 0 {
keyarr = append(keyarr, repoele.KeyPath)
keyPathArr = append(keyPathArr, repoele.KeyPath)
}
if len(repoele.KeyData) > 0 {
keyarr = append(keyarr, string(repoele.KeyData))
keyDataArr = append(keyDataArr, string(repoele.KeyData))
}
}
policyJSON[repo]["keys"] = keyarr
uids := append(getGPGIdFromKeyPath(keyPathArr), getGPGIdFromKeyData(keyDataArr)...)
tempTrustShowOutput.GPGid = strings.Join(uids, ",")
policyJSON[repo]["sigstore"] = ""
registryNamespace := HaveMatchRegistry(repo, registryConfigs)
if registryNamespace != nil {
policyJSON[repo]["sigstore"] = registryNamespace.SigStore
tempTrustShowOutput.Sigstore = registryNamespace.SigStore
}
trustShowOutputMap[repo] = tempTrustShowOutput
}
}
return policyJSON, trustShowOutputMap, nil
} }