Notary delegation integration into docker

Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
Upstream-commit: 1c125f50cfce422b19a15e84c5a3940890fb2e23
Component: engine
This commit is contained in:
Riyaz Faizullabhoy
2015-12-18 18:47:35 -08:00
parent 6ac9b9caaf
commit b741751f8d
50 changed files with 1932 additions and 779 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
@ -238,11 +244,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 +270,27 @@ 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")
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 client.ErrExpired:
return fmt.Errorf("remote repository out-of-date: %v", err)
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: %v", repoName, err)
case signed.ErrInvalidKeyType:
return fmt.Errorf("Error: trust data mismatch for remote repository %s, could be malicious behavior: %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("Error: trust data version is lower than expected for remote repository %s, could be malicious behavior: %v", repoName, err)
case signed.ErrInsufficientSignatures:
return fmt.Errorf("Error: trust data has insufficient signatures for remote repository %s, could be malicious behavior: %v", repoName, err)
}
return err
@ -291,12 +307,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 +320,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
@ -413,7 +429,7 @@ func (cli *DockerCli) trustedPush(repoInfo *registry.RepositoryInfo, tag string,
repo, err := cli.getNotaryRepository(repoInfo, authConfig)
if err != nil {
fmt.Fprintf(cli.out, "Error establishing connection to notary repository: %s\n", err)
fmt.Fprintf(cli.out, "Error establishing connection to notary repository, has a notary server been setup and pointed to by the DOCKER_CONTENT_TRUST_SERVER environment variable?: %s\n", err)
return err
}
@ -429,14 +445,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)
return notaryError(repoInfo.FullName(), err)
}
keys := repo.CryptoService.ListKeys(data.CanonicalRootRole)
@ -455,9 +471,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())
}