Skip to content

Commit 8ec0656

Browse files
Allow credential mapping from dockercfg for canonical ports
1 parent 108739d commit 8ec0656

File tree

2 files changed

+67
-3
lines changed

2 files changed

+67
-3
lines changed

pkg/image/importer/credentials.go

+16-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,12 @@ func (s *SecretCredentialStore) init() credentialprovider.DockerKeyring {
161161

162162
func basicCredentialsFromKeyring(keyring credentialprovider.DockerKeyring, target *url.URL) (string, string) {
163163
// TODO: compare this logic to Docker authConfig in v2 configuration
164-
value := target.Host + target.Path
164+
var value string
165+
if len(target.Scheme) == 0 || target.Scheme == "https" {
166+
value = target.Host + target.Path
167+
} else {
168+
value = target.String()
169+
}
165170

166171
// Lookup(...) expects an image (not a URL path).
167172
// The keyring strips /v1/ and /v2/ version prefixes,
@@ -184,6 +189,16 @@ func basicCredentialsFromKeyring(keyring credentialprovider.DockerKeyring, targe
184189
glog.V(5).Infof("Being asked for %s, trying %s for legacy behavior", target, "docker.io")
185190
return basicCredentialsFromKeyring(keyring, &url.URL{Host: "docker.io"})
186191
}
192+
193+
// try removing the canonical ports for the given requests
194+
if (strings.HasSuffix(target.Host, ":443") && target.Scheme == "https") ||
195+
(strings.HasSuffix(target.Host, ":80") && target.Scheme == "http") {
196+
host := strings.SplitN(target.Host, ":", 2)[0]
197+
glog.V(5).Infof("Being asked for %s, trying %s without port", target, host)
198+
199+
return basicCredentialsFromKeyring(keyring, &url.URL{Scheme: target.Scheme, Host: host, Path: target.Path})
200+
}
201+
187202
glog.V(5).Infof("Unable to find a secret to match %s (%s)", target, value)
188203
return "", ""
189204
}

pkg/image/importer/credentials_test.go

+51-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ import (
66
"reflect"
77
"testing"
88

9+
_ "github.com/openshift/origin/pkg/api/install"
910
"k8s.io/apimachinery/pkg/runtime"
1011
kapi "k8s.io/kubernetes/pkg/api"
1112
"k8s.io/kubernetes/pkg/credentialprovider"
12-
13-
_ "github.com/openshift/origin/pkg/api/install"
1413
)
1514

1615
func TestCredentialsForSecrets(t *testing.T) {
@@ -59,3 +58,53 @@ func TestBasicCredentials(t *testing.T) {
5958
t.Fatalf("unexpected response: %s %s", u, p)
6059
}
6160
}
61+
62+
func Test_basicCredentialsFromKeyring(t *testing.T) {
63+
fn := func(host string, entry credentialprovider.DockerConfigEntry) credentialprovider.DockerKeyring {
64+
k := &credentialprovider.BasicDockerKeyring{}
65+
k.Add(map[string]credentialprovider.DockerConfigEntry{host: entry})
66+
return k
67+
}
68+
def := credentialprovider.DockerConfigEntry{
69+
Username: "local_user",
70+
Password: "local_pass",
71+
}
72+
type args struct {
73+
keyring credentialprovider.DockerKeyring
74+
target *url.URL
75+
}
76+
tests := []struct {
77+
name string
78+
args args
79+
user string
80+
password string
81+
}{
82+
{name: "exact", args: args{keyring: fn("localhost", def), target: &url.URL{Host: "localhost"}}, user: def.Username, password: def.Password},
83+
{name: "https scheme", args: args{keyring: fn("localhost", def), target: &url.URL{Scheme: "https", Host: "localhost"}}, user: def.Username, password: def.Password},
84+
{name: "canonical https", args: args{keyring: fn("localhost", def), target: &url.URL{Scheme: "https", Host: "localhost:443"}}, user: def.Username, password: def.Password},
85+
{name: "only https", args: args{keyring: fn("https://localhost", def), target: &url.URL{Host: "localhost"}}, user: def.Username, password: def.Password},
86+
{name: "only https scheme", args: args{keyring: fn("https://localhost", def), target: &url.URL{Scheme: "https", Host: "localhost"}}, user: def.Username, password: def.Password},
87+
{name: "mismatched scheme - http", args: args{keyring: fn("http://localhost", def), target: &url.URL{Scheme: "https", Host: "localhost"}}, user: def.Username, password: def.Password},
88+
89+
// this is not allowed by the credential keyring, possibly because of insufficient testing
90+
{name: "exact http", args: args{keyring: fn("http://localhost", def), target: &url.URL{Scheme: "http", Host: "localhost:80"}}, user: "", password: ""},
91+
92+
// these should not be allowed
93+
{name: "canonical http", args: args{keyring: fn("localhost", def), target: &url.URL{Scheme: "http", Host: "localhost:80"}}, user: "", password: ""},
94+
{name: "http scheme", args: args{keyring: fn("localhost", def), target: &url.URL{Scheme: "http", Host: "localhost"}}, user: "", password: ""},
95+
{name: "https not canonical", args: args{keyring: fn("localhost", def), target: &url.URL{Scheme: "https", Host: "localhost:80"}}, user: "", password: ""},
96+
{name: "http not canonical", args: args{keyring: fn("localhost", def), target: &url.URL{Scheme: "http", Host: "localhost:443"}}, user: "", password: ""},
97+
{name: "mismatched scheme", args: args{keyring: fn("https://localhost", def), target: &url.URL{Scheme: "http", Host: "localhost"}}, user: "", password: ""},
98+
}
99+
for _, tt := range tests {
100+
t.Run(tt.name, func(t *testing.T) {
101+
user, password := basicCredentialsFromKeyring(tt.args.keyring, tt.args.target)
102+
if user != tt.user {
103+
t.Errorf("basicCredentialsFromKeyring() user = %v, user = %v", user, tt.user)
104+
}
105+
if password != tt.password {
106+
t.Errorf("basicCredentialsFromKeyring() password = %v, password = %v", password, tt.password)
107+
}
108+
})
109+
}
110+
}

0 commit comments

Comments
 (0)