Merge pull request #18887 from riyazdf/notary-delegations
notary delegation integration into docker Upstream-commit: 1c979f758753d921ced122dec3953ddbc35ee67f Component: engine
This commit is contained in:
@ -11,6 +11,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
@ -35,9 +36,14 @@ import (
|
||||
"github.com/docker/notary/passphrase"
|
||||
"github.com/docker/notary/trustmanager"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/tuf/signed"
|
||||
"github.com/docker/notary/tuf/store"
|
||||
)
|
||||
|
||||
var untrusted bool
|
||||
var (
|
||||
releasesRole = path.Join(data.CanonicalTargetsRole, "releases")
|
||||
untrusted bool
|
||||
)
|
||||
|
||||
func addTrustedFlags(fs *flag.FlagSet, verify bool) {
|
||||
var trusted bool
|
||||
@ -189,15 +195,17 @@ func convertTarget(t client.Target) (target, error) {
|
||||
|
||||
func (cli *DockerCli) getPassphraseRetriever() passphrase.Retriever {
|
||||
aliasMap := map[string]string{
|
||||
"root": "root",
|
||||
"snapshot": "repository",
|
||||
"targets": "repository",
|
||||
"root": "root",
|
||||
"snapshot": "repository",
|
||||
"targets": "repository",
|
||||
"targets/releases": "repository",
|
||||
}
|
||||
baseRetriever := passphrase.PromptRetrieverWithInOut(cli.in, cli.out, aliasMap)
|
||||
env := map[string]string{
|
||||
"root": os.Getenv("DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE"),
|
||||
"snapshot": os.Getenv("DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE"),
|
||||
"targets": os.Getenv("DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE"),
|
||||
"root": os.Getenv("DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE"),
|
||||
"snapshot": os.Getenv("DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE"),
|
||||
"targets": os.Getenv("DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE"),
|
||||
"targets/releases": os.Getenv("DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE"),
|
||||
}
|
||||
|
||||
// Backwards compatibility with old env names. We should remove this in 1.10
|
||||
@ -207,10 +215,11 @@ func (cli *DockerCli) getPassphraseRetriever() passphrase.Retriever {
|
||||
fmt.Fprintf(cli.err, "[DEPRECATED] The environment variable DOCKER_CONTENT_TRUST_OFFLINE_PASSPHRASE has been deprecated and will be removed in v1.10. Please use DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE\n")
|
||||
}
|
||||
}
|
||||
if env["snapshot"] == "" || env["targets"] == "" {
|
||||
if env["snapshot"] == "" || env["targets"] == "" || env["targets/releases"] == "" {
|
||||
if passphrase := os.Getenv("DOCKER_CONTENT_TRUST_TAGGING_PASSPHRASE"); passphrase != "" {
|
||||
env["snapshot"] = passphrase
|
||||
env["targets"] = passphrase
|
||||
env["targets/releases"] = passphrase
|
||||
fmt.Fprintf(cli.err, "[DEPRECATED] The environment variable DOCKER_CONTENT_TRUST_TAGGING_PASSPHRASE has been deprecated and will be removed in v1.10. Please use DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE\n")
|
||||
}
|
||||
}
|
||||
@ -238,11 +247,11 @@ func (cli *DockerCli) trustedReference(ref reference.NamedTagged) (reference.Can
|
||||
return nil, err
|
||||
}
|
||||
|
||||
t, err := notaryRepo.GetTargetByName(ref.Tag())
|
||||
t, err := notaryRepo.GetTargetByName(ref.Tag(), releasesRole, data.CanonicalTargetsRole)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r, err := convertTarget(*t)
|
||||
r, err := convertTarget(t.Target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@ -264,17 +273,29 @@ func (cli *DockerCli) tagTrusted(trustedRef reference.Canonical, ref reference.N
|
||||
return cli.client.ImageTag(options)
|
||||
}
|
||||
|
||||
func notaryError(err error) error {
|
||||
func notaryError(repoName string, err error) error {
|
||||
switch err.(type) {
|
||||
case *json.SyntaxError:
|
||||
logrus.Debugf("Notary syntax error: %s", err)
|
||||
return errors.New("no trust data available for remote repository")
|
||||
case client.ErrExpired:
|
||||
return fmt.Errorf("remote repository out-of-date: %v", err)
|
||||
return fmt.Errorf("Error: no trust data available for remote repository %s. Try running notary server and setting DOCKER_CONTENT_TRUST_SERVER to its HTTPS address?", repoName)
|
||||
case signed.ErrExpired:
|
||||
return fmt.Errorf("Error: remote repository %s out-of-date: %v", repoName, err)
|
||||
case trustmanager.ErrKeyNotFound:
|
||||
return fmt.Errorf("signing keys not found: %v", err)
|
||||
return fmt.Errorf("Error: signing keys for remote repository %s not found: %v", repoName, err)
|
||||
case *net.OpError:
|
||||
return fmt.Errorf("error contacting notary server: %v", err)
|
||||
return fmt.Errorf("Error: error contacting notary server: %v", err)
|
||||
case store.ErrMetaNotFound:
|
||||
return fmt.Errorf("Error: trust data missing for remote repository %s or remote repository not found: %v", repoName, err)
|
||||
case signed.ErrInvalidKeyType:
|
||||
return fmt.Errorf("Warning: potential malicious behavior - trust data mismatch for remote repository %s: %v", repoName, err)
|
||||
case signed.ErrNoKeys:
|
||||
return fmt.Errorf("Error: could not find signing keys for remote repository %s: %v", repoName, err)
|
||||
case signed.ErrLowVersion:
|
||||
return fmt.Errorf("Warning: potential malicious behavior - trust data version is lower than expected for remote repository %s: %v", repoName, err)
|
||||
case signed.ErrInsufficientSignatures:
|
||||
return fmt.Errorf("Warning: potential malicious behavior - trust data has insufficient signatures for remote repository %s: %v", repoName, err)
|
||||
case client.ErrRepositoryNotExist:
|
||||
return fmt.Errorf("Error: remote trust data repository not initialized for %s: %v", repoName, err)
|
||||
}
|
||||
|
||||
return err
|
||||
@ -291,12 +312,12 @@ func (cli *DockerCli) trustedPull(repoInfo *registry.RepositoryInfo, ref registr
|
||||
|
||||
if ref.String() == "" {
|
||||
// List all targets
|
||||
targets, err := notaryRepo.ListTargets()
|
||||
targets, err := notaryRepo.ListTargets(releasesRole, data.CanonicalTargetsRole)
|
||||
if err != nil {
|
||||
return notaryError(err)
|
||||
return notaryError(repoInfo.FullName(), err)
|
||||
}
|
||||
for _, tgt := range targets {
|
||||
t, err := convertTarget(*tgt)
|
||||
t, err := convertTarget(tgt.Target)
|
||||
if err != nil {
|
||||
fmt.Fprintf(cli.out, "Skipping target for %q\n", repoInfo.Name())
|
||||
continue
|
||||
@ -304,11 +325,11 @@ func (cli *DockerCli) trustedPull(repoInfo *registry.RepositoryInfo, ref registr
|
||||
refs = append(refs, t)
|
||||
}
|
||||
} else {
|
||||
t, err := notaryRepo.GetTargetByName(ref.String())
|
||||
t, err := notaryRepo.GetTargetByName(ref.String(), releasesRole, data.CanonicalTargetsRole)
|
||||
if err != nil {
|
||||
return notaryError(err)
|
||||
return notaryError(repoInfo.FullName(), err)
|
||||
}
|
||||
r, err := convertTarget(*t)
|
||||
r, err := convertTarget(t.Target)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@ -429,14 +450,14 @@ func (cli *DockerCli) trustedPush(repoInfo *registry.RepositoryInfo, tag string,
|
||||
},
|
||||
Length: int64(target.size),
|
||||
}
|
||||
if err := repo.AddTarget(t); err != nil {
|
||||
if err := repo.AddTarget(t, releasesRole); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = repo.Publish()
|
||||
if _, ok := err.(*client.ErrRepoNotInitialized); !ok {
|
||||
return notaryError(err)
|
||||
if _, ok := err.(client.ErrRepoNotInitialized); !ok {
|
||||
return notaryError(repoInfo.FullName(), err)
|
||||
}
|
||||
|
||||
keys := repo.CryptoService.ListKeys(data.CanonicalRootRole)
|
||||
@ -455,9 +476,9 @@ func (cli *DockerCli) trustedPush(repoInfo *registry.RepositoryInfo, tag string,
|
||||
}
|
||||
|
||||
if err := repo.Initialize(rootKeyID); err != nil {
|
||||
return notaryError(err)
|
||||
return notaryError(repoInfo.FullName(), err)
|
||||
}
|
||||
fmt.Fprintf(cli.out, "Finished initializing %q\n", repoInfo.FullName())
|
||||
|
||||
return notaryError(repo.Publish())
|
||||
return notaryError(repoInfo.FullName(), repo.Publish())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user