mirror of
https://github.com/containers/podman.git
synced 2025-05-21 17:16:22 +08:00
Fix up image sign
in PR 2108
Signed-off-by: Qi Wang <qiwan@redhat.com>
This commit is contained in:
@ -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
|
||||||
|
}
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user