Browse code

Changing trustServer allowed URL behavior

Signed-off-by: Diogo Monica <diogo@docker.com>

Diogo Monica authored on 2015/10/09 03:10:38
Showing 4 changed files
... ...
@@ -15,7 +15,6 @@ import (
15 15
 	"regexp"
16 16
 	"sort"
17 17
 	"strconv"
18
-	"strings"
19 18
 	"time"
20 19
 
21 20
 	"github.com/Sirupsen/logrus"
... ...
@@ -79,17 +78,19 @@ func (cli *DockerCli) certificateDirectory(server string) (string, error) {
79 79
 	return filepath.Join(cliconfig.ConfigDir(), "tls", u.Host), nil
80 80
 }
81 81
 
82
-func trustServer(index *registry.IndexInfo) string {
82
+func trustServer(index *registry.IndexInfo) (string, error) {
83 83
 	if s := os.Getenv("DOCKER_CONTENT_TRUST_SERVER"); s != "" {
84
-		if !strings.HasPrefix(s, "https://") {
85
-			return "https://" + s
84
+		urlObj, err := url.Parse(s)
85
+		if err != nil || urlObj.Scheme != "https" {
86
+			return "", fmt.Errorf("valid https URL required for trust server, got %s", s)
86 87
 		}
87
-		return s
88
+
89
+		return s, nil
88 90
 	}
89 91
 	if index.Official {
90
-		return registry.NotaryServer
92
+		return registry.NotaryServer, nil
91 93
 	}
92
-	return "https://" + index.Name
94
+	return "https://" + index.Name, nil
93 95
 }
94 96
 
95 97
 type simpleCredentialStore struct {
... ...
@@ -101,9 +102,9 @@ func (scs simpleCredentialStore) Basic(u *url.URL) (string, string) {
101 101
 }
102 102
 
103 103
 func (cli *DockerCli) getNotaryRepository(repoInfo *registry.RepositoryInfo, authConfig cliconfig.AuthConfig) (*client.NotaryRepository, error) {
104
-	server := trustServer(repoInfo.Index)
105
-	if !strings.HasPrefix(server, "https://") {
106
-		return nil, errors.New("unsupported scheme: https required for trust server")
104
+	server, err := trustServer(repoInfo.Index)
105
+	if err != nil {
106
+		return nil, err
107 107
 	}
108 108
 
109 109
 	var cfg = tlsconfig.ClientDefault
110 110
new file mode 100644
... ...
@@ -0,0 +1,55 @@
0
+package client
1
+
2
+import (
3
+	"os"
4
+	"testing"
5
+
6
+	"github.com/docker/docker/registry"
7
+)
8
+
9
+func unsetENV() {
10
+	os.Unsetenv("DOCKER_CONTENT_TRUST")
11
+	os.Unsetenv("DOCKER_CONTENT_TRUST_SERVER")
12
+}
13
+
14
+func TestENVTrustServer(t *testing.T) {
15
+	defer unsetENV()
16
+	indexInfo := &registry.IndexInfo{Name: "testserver"}
17
+	if err := os.Setenv("DOCKER_CONTENT_TRUST_SERVER", "https://notary-test.com:5000"); err != nil {
18
+		t.Fatal("Failed to set ENV variable")
19
+	}
20
+	output, err := trustServer(indexInfo)
21
+	expectedStr := "https://notary-test.com:5000"
22
+	if err != nil || output != expectedStr {
23
+		t.Fatalf("Expected server to be %s, got %s", expectedStr, output)
24
+	}
25
+}
26
+
27
+func TestHTTPENVTrustServer(t *testing.T) {
28
+	defer unsetENV()
29
+	indexInfo := &registry.IndexInfo{Name: "testserver"}
30
+	if err := os.Setenv("DOCKER_CONTENT_TRUST_SERVER", "http://notary-test.com:5000"); err != nil {
31
+		t.Fatal("Failed to set ENV variable")
32
+	}
33
+	_, err := trustServer(indexInfo)
34
+	if err == nil {
35
+		t.Fatal("Expected error with invalid scheme")
36
+	}
37
+}
38
+
39
+func TestOfficialTrustServer(t *testing.T) {
40
+	indexInfo := &registry.IndexInfo{Name: "testserver", Official: true}
41
+	output, err := trustServer(indexInfo)
42
+	if err != nil || output != registry.NotaryServer {
43
+		t.Fatalf("Expected server to be %s, got %s", registry.NotaryServer, output)
44
+	}
45
+}
46
+
47
+func TestNonOfficialTrustServer(t *testing.T) {
48
+	indexInfo := &registry.IndexInfo{Name: "testserver", Official: false}
49
+	output, err := trustServer(indexInfo)
50
+	expectedStr := "https://" + indexInfo.Name
51
+	if err != nil || output != expectedStr {
52
+		t.Fatalf("Expected server to be %s, got %s", expectedStr, output)
53
+	}
54
+}
... ...
@@ -148,7 +148,7 @@ func (s *DockerTrustSuite) TestTrustedPushWithFaillingServer(c *check.C) {
148 148
 	dockerCmd(c, "tag", "busybox", repoName)
149 149
 
150 150
 	pushCmd := exec.Command(dockerBinary, "push", repoName)
151
-	s.trustedCmdWithServer(pushCmd, "example/")
151
+	s.trustedCmdWithServer(pushCmd, "https://example.com:81/")
152 152
 	out, _, err := runCommandWithOutput(pushCmd)
153 153
 	if err == nil {
154 154
 		c.Fatalf("Missing error while running trusted push w/ no server")
... ...
@@ -165,7 +165,7 @@ func (s *DockerTrustSuite) TestTrustedPushWithoutServerAndUntrusted(c *check.C)
165 165
 	dockerCmd(c, "tag", "busybox", repoName)
166 166
 
167 167
 	pushCmd := exec.Command(dockerBinary, "push", "--disable-content-trust", repoName)
168
-	s.trustedCmdWithServer(pushCmd, "example/")
168
+	s.trustedCmdWithServer(pushCmd, "https://example.com/")
169 169
 	out, _, err := runCommandWithOutput(pushCmd)
170 170
 	if err != nil {
171 171
 		c.Fatalf("trusted push with no server and --disable-content-trust failed: %s\n%s", err, out)
... ...
@@ -22,6 +22,9 @@ type testNotary struct {
22 22
 	dir string
23 23
 }
24 24
 
25
+const notaryHost = "localhost:4443"
26
+const notaryURL = "https://" + notaryHost
27
+
25 28
 func newTestNotary(c *check.C) (*testNotary, error) {
26 29
 	template := `{
27 30
 	"server": {
... ...
@@ -48,7 +51,7 @@ func newTestNotary(c *check.C) (*testNotary, error) {
48 48
 	if err != nil {
49 49
 		return nil, err
50 50
 	}
51
-	if _, err := fmt.Fprintf(config, template, "localhost:4443"); err != nil {
51
+	if _, err := fmt.Fprintf(config, template, notaryHost); err != nil {
52 52
 		os.RemoveAll(tmp)
53 53
 		return nil, err
54 54
 	}
... ...
@@ -82,10 +85,6 @@ func newTestNotary(c *check.C) (*testNotary, error) {
82 82
 	return testNotary, nil
83 83
 }
84 84
 
85
-func (t *testNotary) address() string {
86
-	return "localhost:4443"
87
-}
88
-
89 85
 func (t *testNotary) Ping() error {
90 86
 	tlsConfig := tlsconfig.ClientDefault
91 87
 	tlsConfig.InsecureSkipVerify = true
... ...
@@ -100,7 +99,7 @@ func (t *testNotary) Ping() error {
100 100
 			TLSClientConfig:     &tlsConfig,
101 101
 		},
102 102
 	}
103
-	resp, err := client.Get(fmt.Sprintf("https://%s/v2/", t.address()))
103
+	resp, err := client.Get(fmt.Sprintf("%s/v2/", notaryURL))
104 104
 	if err != nil {
105 105
 		return err
106 106
 	}
... ...
@@ -117,7 +116,7 @@ func (t *testNotary) Close() {
117 117
 
118 118
 func (s *DockerTrustSuite) trustedCmd(cmd *exec.Cmd) {
119 119
 	pwd := "12345678"
120
-	trustCmdEnv(cmd, s.not.address(), pwd, pwd)
120
+	trustCmdEnv(cmd, notaryURL, pwd, pwd)
121 121
 }
122 122
 
123 123
 func (s *DockerTrustSuite) trustedCmdWithServer(cmd *exec.Cmd, server string) {
... ...
@@ -126,7 +125,7 @@ func (s *DockerTrustSuite) trustedCmdWithServer(cmd *exec.Cmd, server string) {
126 126
 }
127 127
 
128 128
 func (s *DockerTrustSuite) trustedCmdWithPassphrases(cmd *exec.Cmd, offlinePwd, taggingPwd string) {
129
-	trustCmdEnv(cmd, s.not.address(), offlinePwd, taggingPwd)
129
+	trustCmdEnv(cmd, notaryURL, offlinePwd, taggingPwd)
130 130
 }
131 131
 
132 132
 func trustCmdEnv(cmd *exec.Cmd, server, offlinePwd, taggingPwd string) {