Merge pull request #18887 from riyazdf/notary-delegations

notary delegation integration into docker
Upstream-commit: 1c979f758753d921ced122dec3953ddbc35ee67f
Component: engine
This commit is contained in:
Jess Frazelle
2016-01-08 10:37:55 -08:00
54 changed files with 2124 additions and 916 deletions

View File

@ -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())
}