github.com/damirazo/docker@v1.9.0/integration-cli/docker_cli_pull_trusted_test.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os/exec"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/go-check/check"
    11  )
    12  
    13  func (s *DockerTrustSuite) TestTrustedPull(c *check.C) {
    14  	repoName := s.setupTrustedImage(c, "trusted-pull")
    15  
    16  	// Try pull
    17  	pullCmd := exec.Command(dockerBinary, "pull", repoName)
    18  	s.trustedCmd(pullCmd)
    19  	out, _, err := runCommandWithOutput(pullCmd)
    20  	if err != nil {
    21  		c.Fatalf("Error running trusted pull: %s\n%s", err, out)
    22  	}
    23  
    24  	if !strings.Contains(string(out), "Tagging") {
    25  		c.Fatalf("Missing expected output on trusted pull:\n%s", out)
    26  	}
    27  
    28  	dockerCmd(c, "rmi", repoName)
    29  
    30  	// Try untrusted pull to ensure we pushed the tag to the registry
    31  	pullCmd = exec.Command(dockerBinary, "pull", "--disable-content-trust=true", repoName)
    32  	s.trustedCmd(pullCmd)
    33  	out, _, err = runCommandWithOutput(pullCmd)
    34  	if err != nil {
    35  		c.Fatalf("Error running trusted pull: %s\n%s", err, out)
    36  	}
    37  
    38  	if !strings.Contains(string(out), "Status: Downloaded") {
    39  		c.Fatalf("Missing expected output on trusted pull with --disable-content-trust:\n%s", out)
    40  	}
    41  }
    42  
    43  func (s *DockerTrustSuite) TestTrustedIsolatedPull(c *check.C) {
    44  	repoName := s.setupTrustedImage(c, "trusted-isolated-pull")
    45  
    46  	// Try pull (run from isolated directory without trust information)
    47  	pullCmd := exec.Command(dockerBinary, "--config", "/tmp/docker-isolated", "pull", repoName)
    48  	s.trustedCmd(pullCmd)
    49  	out, _, err := runCommandWithOutput(pullCmd)
    50  	if err != nil {
    51  		c.Fatalf("Error running trusted pull: %s\n%s", err, out)
    52  	}
    53  
    54  	if !strings.Contains(string(out), "Tagging") {
    55  		c.Fatalf("Missing expected output on trusted pull:\n%s", out)
    56  	}
    57  
    58  	dockerCmd(c, "rmi", repoName)
    59  }
    60  
    61  func (s *DockerTrustSuite) TestUntrustedPull(c *check.C) {
    62  	repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL)
    63  	// tag the image and upload it to the private registry
    64  	dockerCmd(c, "tag", "busybox", repoName)
    65  	dockerCmd(c, "push", repoName)
    66  	dockerCmd(c, "rmi", repoName)
    67  
    68  	// Try trusted pull on untrusted tag
    69  	pullCmd := exec.Command(dockerBinary, "pull", repoName)
    70  	s.trustedCmd(pullCmd)
    71  	out, _, err := runCommandWithOutput(pullCmd)
    72  	if err == nil {
    73  		c.Fatalf("Error expected when running trusted pull with:\n%s", out)
    74  	}
    75  
    76  	if !strings.Contains(string(out), "no trust data available") {
    77  		c.Fatalf("Missing expected output on trusted pull:\n%s", out)
    78  	}
    79  }
    80  
    81  func (s *DockerTrustSuite) TestPullWhenCertExpired(c *check.C) {
    82  	c.Skip("Currently changes system time, causing instability")
    83  	repoName := s.setupTrustedImage(c, "trusted-cert-expired")
    84  
    85  	// Certificates have 10 years of expiration
    86  	elevenYearsFromNow := time.Now().Add(time.Hour * 24 * 365 * 11)
    87  
    88  	runAtDifferentDate(elevenYearsFromNow, func() {
    89  		// Try pull
    90  		pullCmd := exec.Command(dockerBinary, "pull", repoName)
    91  		s.trustedCmd(pullCmd)
    92  		out, _, err := runCommandWithOutput(pullCmd)
    93  		if err == nil {
    94  			c.Fatalf("Error running trusted pull in the distant future: %s\n%s", err, out)
    95  		}
    96  
    97  		if !strings.Contains(string(out), "could not validate the path to a trusted root") {
    98  			c.Fatalf("Missing expected output on trusted pull in the distant future:\n%s", out)
    99  		}
   100  	})
   101  
   102  	runAtDifferentDate(elevenYearsFromNow, func() {
   103  		// Try pull
   104  		pullCmd := exec.Command(dockerBinary, "pull", "--disable-content-trust", repoName)
   105  		s.trustedCmd(pullCmd)
   106  		out, _, err := runCommandWithOutput(pullCmd)
   107  		if err != nil {
   108  			c.Fatalf("Error running untrusted pull in the distant future: %s\n%s", err, out)
   109  		}
   110  
   111  		if !strings.Contains(string(out), "Status: Downloaded") {
   112  			c.Fatalf("Missing expected output on untrusted pull in the distant future:\n%s", out)
   113  		}
   114  	})
   115  }
   116  
   117  func (s *DockerTrustSuite) TestTrustedPullFromBadTrustServer(c *check.C) {
   118  	repoName := fmt.Sprintf("%v/dockerclievilpull/trusted:latest", privateRegistryURL)
   119  	evilLocalConfigDir, err := ioutil.TempDir("", "evil-local-config-dir")
   120  	if err != nil {
   121  		c.Fatalf("Failed to create local temp dir")
   122  	}
   123  
   124  	// tag the image and upload it to the private registry
   125  	dockerCmd(c, "tag", "busybox", repoName)
   126  
   127  	pushCmd := exec.Command(dockerBinary, "push", repoName)
   128  	s.trustedCmd(pushCmd)
   129  	out, _, err := runCommandWithOutput(pushCmd)
   130  	if err != nil {
   131  		c.Fatalf("Error running trusted push: %s\n%s", err, out)
   132  	}
   133  	if !strings.Contains(string(out), "Signing and pushing trust metadata") {
   134  		c.Fatalf("Missing expected output on trusted push:\n%s", out)
   135  	}
   136  
   137  	dockerCmd(c, "rmi", repoName)
   138  
   139  	// Try pull
   140  	pullCmd := exec.Command(dockerBinary, "pull", repoName)
   141  	s.trustedCmd(pullCmd)
   142  	out, _, err = runCommandWithOutput(pullCmd)
   143  	if err != nil {
   144  		c.Fatalf("Error running trusted pull: %s\n%s", err, out)
   145  	}
   146  
   147  	if !strings.Contains(string(out), "Tagging") {
   148  		c.Fatalf("Missing expected output on trusted pull:\n%s", out)
   149  	}
   150  
   151  	dockerCmd(c, "rmi", repoName)
   152  
   153  	// Kill the notary server, start a new "evil" one.
   154  	s.not.Close()
   155  	s.not, err = newTestNotary(c)
   156  	if err != nil {
   157  		c.Fatalf("Restarting notary server failed.")
   158  	}
   159  
   160  	// In order to make an evil server, lets re-init a client (with a different trust dir) and push new data.
   161  	// tag an image and upload it to the private registry
   162  	dockerCmd(c, "--config", evilLocalConfigDir, "tag", "busybox", repoName)
   163  
   164  	// Push up to the new server
   165  	pushCmd = exec.Command(dockerBinary, "--config", evilLocalConfigDir, "push", repoName)
   166  	s.trustedCmd(pushCmd)
   167  	out, _, err = runCommandWithOutput(pushCmd)
   168  	if err != nil {
   169  		c.Fatalf("Error running trusted push: %s\n%s", err, out)
   170  	}
   171  	if !strings.Contains(string(out), "Signing and pushing trust metadata") {
   172  		c.Fatalf("Missing expected output on trusted push:\n%s", out)
   173  	}
   174  
   175  	// Now, try pulling with the original client from this new trust server. This should fail.
   176  	pullCmd = exec.Command(dockerBinary, "pull", repoName)
   177  	s.trustedCmd(pullCmd)
   178  	out, _, err = runCommandWithOutput(pullCmd)
   179  	if err == nil {
   180  		c.Fatalf("Expected to fail on this pull due to different remote data: %s\n%s", err, out)
   181  	}
   182  
   183  	if !strings.Contains(string(out), "failed to validate data with current trusted certificates") {
   184  		c.Fatalf("Missing expected output on trusted pull:\n%s", out)
   185  	}
   186  }
   187  
   188  func (s *DockerTrustSuite) TestTrustedPullWithExpiredSnapshot(c *check.C) {
   189  	c.Skip("Currently changes system time, causing instability")
   190  	repoName := fmt.Sprintf("%v/dockercliexpiredtimestamppull/trusted:latest", privateRegistryURL)
   191  	// tag the image and upload it to the private registry
   192  	dockerCmd(c, "tag", "busybox", repoName)
   193  
   194  	// Push with default passphrases
   195  	pushCmd := exec.Command(dockerBinary, "push", repoName)
   196  	s.trustedCmd(pushCmd)
   197  	out, _, err := runCommandWithOutput(pushCmd)
   198  	if err != nil {
   199  		c.Fatalf("trusted push failed: %s\n%s", err, out)
   200  	}
   201  
   202  	if !strings.Contains(string(out), "Signing and pushing trust metadata") {
   203  		c.Fatalf("Missing expected output on trusted push:\n%s", out)
   204  	}
   205  
   206  	dockerCmd(c, "rmi", repoName)
   207  
   208  	// Snapshots last for three years. This should be expired
   209  	fourYearsLater := time.Now().Add(time.Hour * 24 * 365 * 4)
   210  
   211  	runAtDifferentDate(fourYearsLater, func() {
   212  		// Try pull
   213  		pullCmd := exec.Command(dockerBinary, "pull", repoName)
   214  		s.trustedCmd(pullCmd)
   215  		out, _, err = runCommandWithOutput(pullCmd)
   216  		if err == nil {
   217  			c.Fatalf("Missing expected error running trusted pull with expired snapshots")
   218  		}
   219  
   220  		if !strings.Contains(string(out), "repository out-of-date") {
   221  			c.Fatalf("Missing expected output on trusted pull with expired snapshot:\n%s", out)
   222  		}
   223  	})
   224  }
   225  
   226  func (s *DockerTrustSuite) TestTrustedOfflinePull(c *check.C) {
   227  	repoName := s.setupTrustedImage(c, "trusted-offline-pull")
   228  
   229  	pullCmd := exec.Command(dockerBinary, "pull", repoName)
   230  	s.trustedCmdWithServer(pullCmd, "https://invalidnotaryserver")
   231  	out, _, err := runCommandWithOutput(pullCmd)
   232  	if err == nil {
   233  		c.Fatalf("Expected error pulling with invalid notary server:\n%s", out)
   234  	}
   235  
   236  	if !strings.Contains(string(out), "error contacting notary server") {
   237  		c.Fatalf("Missing expected output on trusted pull:\n%s", out)
   238  	}
   239  
   240  	// Do valid trusted pull to warm cache
   241  	pullCmd = exec.Command(dockerBinary, "pull", repoName)
   242  	s.trustedCmd(pullCmd)
   243  	out, _, err = runCommandWithOutput(pullCmd)
   244  	if err != nil {
   245  		c.Fatalf("Error running trusted pull: %s\n%s", err, out)
   246  	}
   247  
   248  	if !strings.Contains(string(out), "Tagging") {
   249  		c.Fatalf("Missing expected output on trusted pull:\n%s", out)
   250  	}
   251  
   252  	dockerCmd(c, "rmi", repoName)
   253  
   254  	// Try pull again with invalid notary server, should use cache
   255  	pullCmd = exec.Command(dockerBinary, "pull", repoName)
   256  	s.trustedCmdWithServer(pullCmd, "https://invalidnotaryserver")
   257  	out, _, err = runCommandWithOutput(pullCmd)
   258  	if err != nil {
   259  		c.Fatalf("Error running trusted pull: %s\n%s", err, out)
   260  	}
   261  
   262  	if !strings.Contains(string(out), "Tagging") {
   263  		c.Fatalf("Missing expected output on trusted pull:\n%s", out)
   264  	}
   265  }