Skip to content

Commit

Permalink
Notary delegation integration into docker
Browse files Browse the repository at this point in the history
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
  • Loading branch information
riyazdf committed Jan 8, 2016
1 parent 6213cc9 commit 1c125f5
Show file tree
Hide file tree
Showing 50 changed files with 1,914 additions and 761 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ RUN set -x \
&& rm -rf "$GOPATH"

# Install notary server
ENV NOTARY_COMMIT 8e8122eb5528f621afcd4e2854c47302f17392f7
ENV NOTARY_COMMIT 30c488b3b4c62fdbc2c1eae7cf3b62ca73f95fad
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \
Expand Down
54 changes: 35 additions & 19 deletions api/client/trust.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/http"
"net/url"
"os"
"path"
"path/filepath"
"regexp"
"sort"
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand All @@ -291,24 +307,24 @@ 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
}
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

Expand Down Expand Up @@ -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
}

Expand All @@ -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)
Expand All @@ -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())
}
4 changes: 3 additions & 1 deletion hack/vendor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ clone git github.com/boltdb/bolt v1.1.0
clone git github.com/docker/distribution 568bf038af6d65b376165d02886b1c7fcaef1f61
clone git github.com/vbatts/tar-split v0.9.11

clone git github.com/docker/notary 45de2828b5e0083bfb4e9a5a781eddb05e2ef9d0
# get desired notary commit, might also need to be updated in Dockerfile
clone git github.com/docker/notary 30c488b3b4c62fdbc2c1eae7cf3b62ca73f95fad

clone git google.golang.org/grpc 174192fc93efcb188fc8f46ca447f0da606b6885 https://github.com/grpc/grpc-go.git
clone git github.com/miekg/pkcs11 80f102b5cac759de406949c47f0928b99bd64cdf
clone git github.com/jfrazelle/go v1.5.1-1
Expand Down
2 changes: 1 addition & 1 deletion integration-cli/docker_cli_build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5805,7 +5805,7 @@ func (s *DockerTrustSuite) TestTrustedBuildUntrustedTag(c *check.C) {
c.Fatalf("Expected error on trusted build with untrusted tag: %s\n%s", err, out)
}

if !strings.Contains(out, fmt.Sprintf("no trust data available")) {
if !strings.Contains(out, fmt.Sprintf("trust data unavailable")) {
c.Fatalf("Unexpected output on trusted build with untrusted tag:\n%s", out)
}
}
Expand Down
2 changes: 1 addition & 1 deletion integration-cli/docker_cli_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ func (s *DockerTrustSuite) TestUntrustedCreate(c *check.C) {
s.trustedCmd(createCmd)
out, _, err := runCommandWithOutput(createCmd)
c.Assert(err, check.Not(check.IsNil))
c.Assert(string(out), checker.Contains, "no trust data available", check.Commentf("Missing expected output on trusted create:\n%s", out))
c.Assert(string(out), checker.Contains, "trust data unavailable", check.Commentf("Missing expected output on trusted create:\n%s", out))

}

Expand Down
2 changes: 1 addition & 1 deletion integration-cli/docker_cli_pull_trusted_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (s *DockerTrustSuite) TestUntrustedPull(c *check.C) {
out, _, err := runCommandWithOutput(pullCmd)

c.Assert(err, check.NotNil, check.Commentf(out))
c.Assert(string(out), checker.Contains, "no trust data available", check.Commentf(out))
c.Assert(string(out), checker.Contains, "trust data unavailable", check.Commentf(out))
}

func (s *DockerTrustSuite) TestPullWhenCertExpired(c *check.C) {
Expand Down
25 changes: 23 additions & 2 deletions integration-cli/docker_cli_push_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,17 @@ func (s *DockerTrustSuite) TestTrustedPush(c *check.C) {
out, _, err := runCommandWithOutput(pushCmd)
c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out))
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push"))

// Try pull after push
pullCmd := exec.Command(dockerBinary, "pull", repoName)
s.trustedCmd(pullCmd)
out, _, err = runCommandWithOutput(pullCmd)
c.Assert(err, check.IsNil, check.Commentf(out))
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
}

func (s *DockerTrustSuite) TestTrustedPushWithEnvPasswords(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL)
repoName := fmt.Sprintf("%v/dockerclienv/trusted:latest", privateRegistryURL)
// tag the image and upload it to the private registry
dockerCmd(c, "tag", "busybox", repoName)

Expand All @@ -127,6 +134,13 @@ func (s *DockerTrustSuite) TestTrustedPushWithEnvPasswords(c *check.C) {
out, _, err := runCommandWithOutput(pushCmd)
c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out))
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push"))

// Try pull after push
pullCmd := exec.Command(dockerBinary, "pull", repoName)
s.trustedCmd(pullCmd)
out, _, err = runCommandWithOutput(pullCmd)
c.Assert(err, check.IsNil, check.Commentf(out))
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
}

// This test ensures backwards compatibility with old ENV variables. Should be
Expand Down Expand Up @@ -168,7 +182,7 @@ func (s *DockerTrustSuite) TestTrustedPushWithoutServerAndUntrusted(c *check.C)
}

func (s *DockerTrustSuite) TestTrustedPushWithExistingTag(c *check.C) {
repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL)
repoName := fmt.Sprintf("%v/dockerclitag/trusted:latest", privateRegistryURL)
// tag the image and upload it to the private registry
dockerCmd(c, "tag", "busybox", repoName)
dockerCmd(c, "push", repoName)
Expand All @@ -178,6 +192,13 @@ func (s *DockerTrustSuite) TestTrustedPushWithExistingTag(c *check.C) {
out, _, err := runCommandWithOutput(pushCmd)
c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out))
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag"))

// Try pull after push
pullCmd := exec.Command(dockerBinary, "pull", repoName)
s.trustedCmd(pullCmd)
out, _, err = runCommandWithOutput(pullCmd)
c.Assert(err, check.IsNil, check.Commentf(out))
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
}

func (s *DockerTrustSuite) TestTrustedPushWithExistingSignedTag(c *check.C) {
Expand Down
2 changes: 1 addition & 1 deletion integration-cli/docker_cli_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3087,7 +3087,7 @@ func (s *DockerTrustSuite) TestUntrustedRun(c *check.C) {
c.Fatalf("Error expected when running trusted run with:\n%s", out)
}

if !strings.Contains(string(out), "no trust data available") {
if !strings.Contains(string(out), "trust data unavailable") {
c.Fatalf("Missing expected output on trusted run:\n%s", out)
}
}
Expand Down
20 changes: 14 additions & 6 deletions integration-cli/trust_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ const notaryURL = "https://" + notaryHost
func newTestNotary(c *check.C) (*testNotary, error) {
template := `{
"server": {
"addr": "%s",
"tls_key_file": "fixtures/notary/localhost.key",
"tls_cert_file": "fixtures/notary/localhost.cert"
"http_addr": "%s",
"tls_key_file": "%s",
"tls_cert_file": "%s"
},
"trust_service": {
"type": "local",
Expand All @@ -39,8 +39,11 @@ func newTestNotary(c *check.C) (*testNotary, error) {
"key_algorithm": "ed25519"
},
"logging": {
"level": 5
}
"level": "debug"
},
"storage": {
"backend": "memory"
}
}`
tmp, err := ioutil.TempDir("", "notary-test-")
if err != nil {
Expand All @@ -51,7 +54,12 @@ func newTestNotary(c *check.C) (*testNotary, error) {
if err != nil {
return nil, err
}
if _, err := fmt.Fprintf(config, template, notaryHost); err != nil {

workingDir, err := os.Getwd()
if err != nil {
return nil, err
}
if _, err := fmt.Fprintf(config, template, notaryHost, filepath.Join(workingDir, "fixtures/notary/localhost.key"), filepath.Join(workingDir, "fixtures/notary/localhost.cert")); err != nil {
os.RemoveAll(tmp)
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion vendor/src/github.com/docker/notary/Dockerfile.server
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ RUN go install \
${NOTARYPKG}/cmd/notary-server

ENTRYPOINT [ "notary-server" ]
CMD [ "-config", "cmd/notary-server/config.json" ]
CMD [ "-config=fixtures/server-config-local.json" ]
2 changes: 1 addition & 1 deletion vendor/src/github.com/docker/notary/Dockerfile.signer
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ RUN go install \


ENTRYPOINT [ "notary-signer" ]
CMD [ "-config=cmd/notary-signer/config.json" ]
CMD [ "-config=fixtures/signer-config-local.json" ]
57 changes: 52 additions & 5 deletions vendor/src/github.com/docker/notary/MAINTAINERS
Original file line number Diff line number Diff line change
@@ -1,5 +1,52 @@
David Lawrence <david.lawrence@docker.com> (@endophage)
Ying Li <ying.li@docker.com> (@cyli)
Nathan McCauley <nathan.mccauley@docker.com> (@NathanMcCauley)
Derek McGowan <derek@docker.com> (@dmcgowan)
Diogo Monica <diogo@docker.com> (@diogomonica)
# Notary maintainers file
#
# This file describes who runs the docker/notary project and how.
# This is a living document - if you see something out of date or missing, speak up!
#
# It is structured to be consumable by both humans and programs.
# To extract its contents programmatically, use any TOML-compliant parser.
#
# This file is compiled into the MAINTAINERS file in docker/opensource.
#
[Org]
[Org."Core maintainers"]
people = [
"cyli",
"diogomonica",
"dmcgowan",
"endophage",
"nathanmccauley",
]

[people]

# A reference list of all people associated with the project.
# All other sections should refer to people by their canonical key
# in the people section.

# ADD YOURSELF HERE IN ALPHABETICAL ORDER

[people.cyli]
Name = "Ying Li"
Email = "ying.li@docker.com"
GitHub = "cyli"

[people.diogomonica]
Name = "Diogo Monica"
Email = "diogo@docker.com"
GitHub = "diogomonica"

[people.dmcgowan]
Name = "Derek McGowan"
Email = "derek@docker.com"
GitHub = "dmcgowan"

[people.endophage]
Name = "David Lawrence"
Email = "david.lawrence@docker.com"
GitHub = "endophage"

[people.nathanmccauley]
Name = "Nathan McCauley"
Email = "nathan.mccauley@docker.com"
GitHub = "nathanmccauley"
11 changes: 8 additions & 3 deletions vendor/src/github.com/docker/notary/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ _space := $(empty) $(empty)

# go cover test variables
COVERDIR=.cover
COVERPROFILE=$(COVERDIR)/cover.out
COVERPROFILE?=$(COVERDIR)/cover.out
COVERMODE=count
PKGS = $(shell go list ./... | tr '\n' ' ')

Expand All @@ -43,8 +43,8 @@ GO_VERSION = $(shell go version | awk '{print $$3}')
.DEFAULT: default

go_version:
ifneq ("$(GO_VERSION)", "go1.5.1")
$(error Requires go version 1.5.1 - found $(GO_VERSION))
ifeq (,$(findstring go1.5.,$(GO_VERSION)))
$(error Requires go version 1.5.x - found $(GO_VERSION))
else
@echo
endif
Expand Down Expand Up @@ -73,6 +73,11 @@ ${PREFIX}/bin/notary-signer: NOTARY_VERSION $(shell find . -type f -name '*.go')

vet: go_version
@echo "+ $@"
ifeq ($(shell uname -s), Darwin)
@test -z "$(shell find . -iname *test*.go | grep -v _test.go | grep -v Godeps | xargs echo "This file should end with '_test':" | tee /dev/stderr)"
else
@test -z "$(shell find . -iname *test*.go | grep -v _test.go | grep -v Godeps | xargs -r echo "This file should end with '_test':" | tee /dev/stderr)"
endif
@test -z "$$(go tool vet -printf=false . 2>&1 | grep -v Godeps/_workspace/src/ | tee /dev/stderr)"

fmt:
Expand Down
2 changes: 1 addition & 1 deletion vendor/src/github.com/docker/notary/NOTARY_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0-rc1
0.2
Loading

0 comments on commit 1c125f5

Please sign in to comment.