Pārlūkot izejas kodu

Add tests simulating an evil server

Signed-off-by: Nathan McCauley <nathan.mccauley@docker.com>
Nathan McCauley 10 gadi atpakaļ
vecāks
revīzija
268fa5af47

+ 72 - 0
integration-cli/docker_cli_create_test.go

@@ -12,6 +12,7 @@ import (
 
 	"github.com/docker/docker/pkg/nat"
 	"github.com/go-check/check"
+	"io/ioutil"
 )
 
 // Make sure we can create a simple container with some args
@@ -376,3 +377,74 @@ func (s *DockerTrustSuite) TestCreateWhenCertExpired(c *check.C) {
 		}
 	})
 }
+
+func (s *DockerTrustSuite) TestTrustedCreateFromBadTrustServer(c *check.C) {
+	repoName := fmt.Sprintf("%v/dockerclievilcreate/trusted:latest", privateRegistryURL)
+	evilLocalConfigDir, err := ioutil.TempDir("", "evil-local-config-dir")
+	if err != nil {
+		c.Fatalf("Failed to create local temp dir")
+	}
+
+	// tag the image and upload it to the private registry
+	dockerCmd(c, "tag", "busybox", repoName)
+
+	pushCmd := exec.Command(dockerBinary, "push", repoName)
+	s.trustedCmd(pushCmd)
+	out, _, err := runCommandWithOutput(pushCmd)
+	if err != nil {
+		c.Fatalf("Error creating trusted push: %s\n%s", err, out)
+	}
+	if !strings.Contains(string(out), "Signing and pushing trust metadata") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+
+	dockerCmd(c, "rmi", repoName)
+
+	// Try create
+	createCmd := exec.Command(dockerBinary, "create", repoName)
+	s.trustedCmd(createCmd)
+	out, _, err = runCommandWithOutput(createCmd)
+	if err != nil {
+		c.Fatalf("Error creating trusted create: %s\n%s", err, out)
+	}
+
+	if !strings.Contains(string(out), "Tagging") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+
+	dockerCmd(c, "rmi", repoName)
+
+	// Kill the notary server, start a new "evil" one.
+	s.not.Close()
+	s.not, err = newTestNotary(c)
+	if err != nil {
+		c.Fatalf("Restarting notary server failed.")
+	}
+
+	// In order to make an evil server, lets re-init a client (with a different trust dir) and push new data.
+	// tag an image and upload it to the private registry
+	dockerCmd(c, "--config", evilLocalConfigDir, "tag", "busybox", repoName)
+
+	// Push up to the new server
+	pushCmd = exec.Command(dockerBinary, "--config", evilLocalConfigDir, "push", repoName)
+	s.trustedCmd(pushCmd)
+	out, _, err = runCommandWithOutput(pushCmd)
+	if err != nil {
+		c.Fatalf("Error creating trusted push: %s\n%s", err, out)
+	}
+	if !strings.Contains(string(out), "Signing and pushing trust metadata") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+
+	// Now, try creating with the original client from this new trust server. This should fail.
+	createCmd = exec.Command(dockerBinary, "create", repoName)
+	s.trustedCmd(createCmd)
+	out, _, err = runCommandWithOutput(createCmd)
+	if err == nil {
+		c.Fatalf("Expected to fail on this create due to different remote data: %s\n%s", err, out)
+	}
+
+	if !strings.Contains(string(out), "failed to validate integrity of roots") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+}

+ 72 - 0
integration-cli/docker_cli_pull_test.go

@@ -7,6 +7,7 @@ import (
 	"time"
 
 	"github.com/go-check/check"
+	"io/ioutil"
 )
 
 // See issue docker/docker#8141
@@ -256,3 +257,74 @@ func (s *DockerTrustSuite) TestPullWhenCertExpired(c *check.C) {
 		}
 	})
 }
+
+func (s *DockerTrustSuite) TestTrustedPullFromBadTrustServer(c *check.C) {
+	repoName := fmt.Sprintf("%v/dockerclievilpull/trusted:latest", privateRegistryURL)
+	evilLocalConfigDir, err := ioutil.TempDir("", "evil-local-config-dir")
+	if err != nil {
+		c.Fatalf("Failed to create local temp dir")
+	}
+
+	// tag the image and upload it to the private registry
+	dockerCmd(c, "tag", "busybox", repoName)
+
+	pushCmd := exec.Command(dockerBinary, "push", repoName)
+	s.trustedCmd(pushCmd)
+	out, _, err := runCommandWithOutput(pushCmd)
+	if err != nil {
+		c.Fatalf("Error running trusted push: %s\n%s", err, out)
+	}
+	if !strings.Contains(string(out), "Signing and pushing trust metadata") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+
+	dockerCmd(c, "rmi", repoName)
+
+	// Try pull
+	pullCmd := exec.Command(dockerBinary, "pull", repoName)
+	s.trustedCmd(pullCmd)
+	out, _, err = runCommandWithOutput(pullCmd)
+	if err != nil {
+		c.Fatalf("Error running trusted pull: %s\n%s", err, out)
+	}
+
+	if !strings.Contains(string(out), "Tagging") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+
+	dockerCmd(c, "rmi", repoName)
+
+	// Kill the notary server, start a new "evil" one.
+	s.not.Close()
+	s.not, err = newTestNotary(c)
+	if err != nil {
+		c.Fatalf("Restarting notary server failed.")
+	}
+
+	// In order to make an evil server, lets re-init a client (with a different trust dir) and push new data.
+	// tag an image and upload it to the private registry
+	dockerCmd(c, "--config", evilLocalConfigDir, "tag", "busybox", repoName)
+
+	// Push up to the new server
+	pushCmd = exec.Command(dockerBinary, "--config", evilLocalConfigDir, "push", repoName)
+	s.trustedCmd(pushCmd)
+	out, _, err = runCommandWithOutput(pushCmd)
+	if err != nil {
+		c.Fatalf("Error running trusted push: %s\n%s", err, out)
+	}
+	if !strings.Contains(string(out), "Signing and pushing trust metadata") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+
+	// Now, try pulling with the original client from this new trust server. This should fail.
+	pullCmd = exec.Command(dockerBinary, "pull", repoName)
+	s.trustedCmd(pullCmd)
+	out, _, err = runCommandWithOutput(pullCmd)
+	if err == nil {
+		c.Fatalf("Expected to fail on this pull due to different remote data: %s\n%s", err, out)
+	}
+
+	if !strings.Contains(string(out), "failed to validate integrity of roots") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+}

+ 71 - 0
integration-cli/docker_cli_run_test.go

@@ -2632,3 +2632,74 @@ func (s *DockerTrustSuite) TestRunWhenCertExpired(c *check.C) {
 		}
 	})
 }
+
+func (s *DockerTrustSuite) TestTrustedRunFromBadTrustServer(c *check.C) {
+	repoName := fmt.Sprintf("%v/dockerclievilrun/trusted:latest", privateRegistryURL)
+	evilLocalConfigDir, err := ioutil.TempDir("", "evil-local-config-dir")
+	if err != nil {
+		c.Fatalf("Failed to create local temp dir")
+	}
+
+	// tag the image and upload it to the private registry
+	dockerCmd(c, "tag", "busybox", repoName)
+
+	pushCmd := exec.Command(dockerBinary, "push", repoName)
+	s.trustedCmd(pushCmd)
+	out, _, err := runCommandWithOutput(pushCmd)
+	if err != nil {
+		c.Fatalf("Error running trusted push: %s\n%s", err, out)
+	}
+	if !strings.Contains(string(out), "Signing and pushing trust metadata") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+
+	dockerCmd(c, "rmi", repoName)
+
+	// Try run
+	runCmd := exec.Command(dockerBinary, "run", repoName)
+	s.trustedCmd(runCmd)
+	out, _, err = runCommandWithOutput(runCmd)
+	if err != nil {
+		c.Fatalf("Error running trusted run: %s\n%s", err, out)
+	}
+
+	if !strings.Contains(string(out), "Tagging") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+
+	dockerCmd(c, "rmi", repoName)
+
+	// Kill the notary server, start a new "evil" one.
+	s.not.Close()
+	s.not, err = newTestNotary(c)
+	if err != nil {
+		c.Fatalf("Restarting notary server failed.")
+	}
+
+	// In order to make an evil server, lets re-init a client (with a different trust dir) and push new data.
+	// tag an image and upload it to the private registry
+	dockerCmd(c, "--config", evilLocalConfigDir, "tag", "busybox", repoName)
+
+	// Push up to the new server
+	pushCmd = exec.Command(dockerBinary, "--config", evilLocalConfigDir, "push", repoName)
+	s.trustedCmd(pushCmd)
+	out, _, err = runCommandWithOutput(pushCmd)
+	if err != nil {
+		c.Fatalf("Error running trusted push: %s\n%s", err, out)
+	}
+	if !strings.Contains(string(out), "Signing and pushing trust metadata") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+
+	// Now, try running with the original client from this new trust server. This should fail.
+	runCmd = exec.Command(dockerBinary, "run", repoName)
+	s.trustedCmd(runCmd)
+	out, _, err = runCommandWithOutput(runCmd)
+	if err == nil {
+		c.Fatalf("Expected to fail on this run due to different remote data: %s\n%s", err, out)
+	}
+
+	if !strings.Contains(string(out), "failed to validate integrity of roots") {
+		c.Fatalf("Missing expected output on trusted push:\n%s", out)
+	}
+}

+ 0 - 11
integration-cli/docker_utils.go

@@ -1267,17 +1267,6 @@ func setupNotary(c *check.C) *testNotary {
 		c.Fatal(err)
 	}
 
-	// Wait for notary to be ready to serve requests.
-	for i := 1; i <= 5; i++ {
-		if err = ts.Ping(); err == nil {
-			break
-		}
-		time.Sleep(10 * time.Millisecond * time.Duration(i*i))
-	}
-
-	if err != nil {
-		c.Fatalf("Timeout waiting for test notary to become available: %s", err)
-	}
 	return ts
 }
 

+ 17 - 2
integration-cli/trust_server.go

@@ -60,10 +60,25 @@ func newTestNotary(c *check.C) (*testNotary, error) {
 		}
 		return nil, err
 	}
-	return &testNotary{
+
+	testNotary := &testNotary{
 		cmd: cmd,
 		dir: tmp,
-	}, nil
+	}
+
+	// Wait for notary to be ready to serve requests.
+	for i := 1; i <= 5; i++ {
+		if err = testNotary.Ping(); err == nil {
+			break
+		}
+		time.Sleep(10 * time.Millisecond * time.Duration(i*i))
+	}
+
+	if err != nil {
+		c.Fatalf("Timeout waiting for test notary to become available: %s", err)
+	}
+
+	return testNotary, nil
 }
 
 func (t *testNotary) address() string {