Fix docker style cert loading.

The certs dir parsing was skipping over files instead of reading them,
as such the certs would never load.

It was also stating the file name rather than the full path for cert
pairs.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff 2021-01-28 23:50:10 +00:00
parent 9d5c1165a6
commit 1fd99e24a2
2 changed files with 118 additions and 4 deletions

View File

@ -82,7 +82,6 @@ func ConfigureHosts(ctx context.Context, options HostOptions) docker.RegistryHos
return nil, err
}
}
}
// If hosts was not set, add a default host
@ -490,7 +489,7 @@ func loadCertFiles(ctx context.Context, certsDir string) ([]hostConfig, error) {
}
hosts := make([]hostConfig, 1)
for _, f := range fs {
if !f.IsDir() {
if f.IsDir() {
continue
}
if strings.HasSuffix(f.Name(), ".crt") {
@ -501,9 +500,9 @@ func loadCertFiles(ctx context.Context, certsDir string) ([]hostConfig, error) {
certFile := f.Name()
pair[0] = filepath.Join(certsDir, certFile)
// Check if key also exists
keyFile := certFile[:len(certFile)-5] + ".key"
keyFile := filepath.Join(certsDir, certFile[:len(certFile)-5]+".key")
if _, err := os.Stat(keyFile); err == nil {
pair[1] = filepath.Join(certsDir, keyFile)
pair[1] = keyFile
} else if !os.IsNotExist(err) {
return nil, err
}

View File

@ -20,7 +20,9 @@ import (
"bytes"
"context"
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"testing"
@ -190,6 +192,87 @@ ca = "/etc/path/default"
}
}
func TestLoadCertFiles(t *testing.T) {
dir, err := ioutil.TempDir("", t.Name())
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
type testCase struct {
input hostConfig
}
cases := map[string]testCase{
"crt only": {
input: hostConfig{host: "testing.io", caCerts: []string{filepath.Join(dir, "testing.io", "ca.crt")}},
},
"crt and cert pair": {
input: hostConfig{
host: "testing.io",
caCerts: []string{filepath.Join(dir, "testing.io", "ca.crt")},
clientPairs: [][2]string{
{
filepath.Join(dir, "testing.io", "client.cert"),
filepath.Join(dir, "testing.io", "client.key"),
},
},
},
},
"cert pair only": {
input: hostConfig{
host: "testing.io",
clientPairs: [][2]string{
{
filepath.Join(dir, "testing.io", "client.cert"),
filepath.Join(dir, "testing.io", "client.key"),
},
},
},
},
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
hostDir := filepath.Join(dir, tc.input.host)
if err := os.MkdirAll(hostDir, 0700); err != nil {
t.Fatal(err)
}
defer os.RemoveAll(hostDir)
for _, f := range tc.input.caCerts {
if err := ioutil.WriteFile(f, testKey, 0600); err != nil {
t.Fatal(err)
}
}
for _, pair := range tc.input.clientPairs {
if err := ioutil.WriteFile(pair[0], testKey, 0600); err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(pair[1], testKey, 0600); err != nil {
t.Fatal(err)
}
}
configs, err := loadHostDir(context.Background(), hostDir)
if err != nil {
t.Fatal(err)
}
if len(configs) != 1 {
t.Fatalf("\nexpected:\n%+v\ngot:\n%+v", tc.input, configs)
}
cfg := configs[0]
cfg.host = tc.input.host
if !compareHostConfig(cfg, tc.input) {
t.Errorf("\nexpected:\n%+v:\n\ngot:\n%+v", tc.input, cfg)
}
})
}
}
func compareRegistryHost(j, k docker.RegistryHost) bool {
if j.Scheme != k.Scheme {
return false
@ -283,3 +366,35 @@ func printHostConfig(hc []hostConfig) string {
}
return b.String()
}
var (
testKey = []byte(`-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDa+zvPgFXwra4S
0DzEWRgZHxVTDG1sJsnN/jOaHCNpRyABGVW5kdei9WFWv3dpiELI+guQMjdUL++w
M68bs6cXKW+1nW6u5uWuGwklOwkoKoeHkkn/vHef7ybk+5qdk6AYY0DKQsrBBOvj
f0WAnG+1xi8VIOEBmce0/47MexOiuILVkjokgdmDCOc8ShkT6/EJTCsI1wDew/4G
9IiRzw2xSM0ZATAtEC3HEBRLJGWZQtuKlLCuzJ+erOWUcg2cjnSgR3PmaAXE//5g
SoeqEbtTo1satf9AR4VvreIAI8m0eyo8ABMLTkZovEFcUUHetL63hdqItjCeRfrQ
zK4LMRFbAgMBAAECggEBAJtP6UHo0gtcA8SQMSlJz4+xvhwjClDUyfjyPIMnRe5b
ZdWhtG1jhT+tLhaqwfT1kfidcCobk6aAQU4FukK5jt8cooB7Yo9mcKylvDzNvFbi
ozGCjj113JpwsnNiCG2O0NO7Qa6y5L810GCQWik3yvtvzuD7atsJyN0VDKD3Ahw7
1X8z76grZFlhVMCTAA3vAJ2y2p3sd+TGC/PIhnsvChwxEorGCnMj93mBaUI7zZRY
EZhlk4ZvC9sUvlVUuYC+wAHjasgN9s3AzsOBSx+Xt3NaXQHzhL0mVo/vu/pjjFBs
WBLR1PBoIfveTJPOp+Hrr4cuCK0NuX9sWlWPYLl5A2ECgYEA5fq3n4PhbJ2BuTS5
AVgOmjRpk1eogb6aSY+cx7Mr++ADF9EYXc5tgKoUsDeeiiyK2lv6IKavoTWT1kdd
shiclyEzp2CxG5GtbC/g2XHiBLepgo1fjfev3btCmIeGVBjglOx4F3gEsRygrAID
zcz94m2I+uqLT8hvWnccIqScglkCgYEA88H2ji4Nvx6TmqCLcER0vNDVoxxDfgGb
iohvenD2jmmdTnezTddsgECAI8L0BPNS/0vBCduTjs5BqhKbIfQvuK5CANMUcxuQ
twWH8kPvTYJVgsmWP6sSXSz3PohWC5EA9xACExGtyN6d7sLUCV0SBhjlcgMvGuDM
lP6NjyyWctMCgYBKdfGr+QQsqZaNw48+6ybXMK8aIKCTWYYU2SW21sEf7PizZmTQ
Qnzb0rWeFHQFYsSWTH9gwPdOZ8107GheuG9C02IpCDpvpawTwjC31pKKWnjMpz9P
9OkBDpdSUVbhtahJL4L2fkpumck/x+s5X+y3uiVGsFfovgmnrbbzVH7ECQKBgQCC
MYs7DaYR+obkA/P2FtozL2esIyB5YOpu58iDIWrPTeHTU2PVo8Y0Cj9m2m3zZvNh
oFiOp1T85XV1HVL2o7IJdimSvyshAAwfdTjTUS2zvHVn0bwKbZj1Y1r7b15l9yEI
1OgGv16O9zhrmmweRDOoRgvnBYRXWtJqkjuRyULiOQKBgQC/lSYigV32Eb8Eg1pv
7OcPWv4qV4880lRE0MXuQ4VFa4+pqvdziYFYQD4jDYJ4IX9l//bsobL0j7z0P0Gk
wDFti9bRwRoO1ntqoA8n2pDLlLRGl0dyjB6fHzp27oqtyf1HRlHiow7Gqx5b5JOk
tycYKwA3DuaSyqPe6MthLneq8w==
-----END PRIVATE KEY-----
`)
)