Fix #1403: sslCAInfo config lookup when host in config doesn't have a trailing slash

appendRootCAsForHostFromGitconfig() modified to check hosts with and without a trailing slash.

Cert unit tests made "table driven" and extended to cover this case.
This commit is contained in:
Dakota Hawkins 2016-07-28 15:32:18 -04:00
parent d0028c6e03
commit 24cab8ad99
2 changed files with 58 additions and 40 deletions

@ -51,10 +51,14 @@ func appendRootCAsForHostFromGitconfig(pool *x509.CertPool, host string) *x509.C
if cafile := config.Config.Getenv("GIT_SSL_CAINFO"); len(cafile) > 0 {
return appendCertsFromFile(pool, cafile)
}
// http.<url>.sslcainfo
// http.<url>/.sslcainfo or http.<url>.sslcainfo
// we know we have simply "host" or "host:port"
key := fmt.Sprintf("http.https://%v/.sslcainfo", host)
if cafile, ok := config.Config.GitConfig(key); ok {
hostKeyWithSlash := fmt.Sprintf("http.https://%v/.sslcainfo", host)
if cafile, ok := config.Config.GitConfig(hostKeyWithSlash); ok {
return appendCertsFromFile(pool, cafile)
}
hostKeyWithoutSlash := fmt.Sprintf("http.https://%v.sslcainfo", host)
if cafile, ok := config.Config.GitConfig(hostKeyWithoutSlash); ok {
return appendCertsFromFile(pool, cafile)
}
// http.sslcainfo

@ -1,6 +1,7 @@
package httputil
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
@ -34,6 +35,19 @@ aW6vZwkA+ccj/pDTx8LBe2lnpatrFeIt6znAUJW3G8r6SFHKVBWHwmESZS4kxhjx
NpW5Hh0w4/5iIetCkJ0=
-----END CERTIFICATE-----`
var sslCAInfoConfigHostNames = []string{
"git-lfs.local",
"git-lfs.local/",
}
var sslCAInfoMatchedHostTests = []struct {
hostName string
shouldMatch bool
}{
{"git-lfs.local", true},
{"git-lfs.local:8443", false},
{"wronghost.com", false},
}
func TestCertFromSSLCAInfoConfig(t *testing.T) {
defer config.Config.ResetConfig()
@ -45,32 +59,38 @@ func TestCertFromSSLCAInfoConfig(t *testing.T) {
assert.Nil(t, err, "Error writing temp cert file")
tempfile.Close()
config.Config.ClearConfig()
config.Config.SetConfig("http.https://git-lfs.local/.sslcainfo", tempfile.Name())
// Test http.<url>.sslcainfo
for _, hostName := range sslCAInfoConfigHostNames {
config.Config.ClearConfig()
// Should match
pool := getRootCAsForHost("git-lfs.local")
assert.NotNil(t, pool)
hostKey := fmt.Sprintf("http.https://%v.sslcainfo", hostName)
config.Config.SetConfig(hostKey, tempfile.Name())
// Shouldn't match
pool = getRootCAsForHost("wronghost.com")
assert.Nil(t, pool)
for _, matchedHostTest := range sslCAInfoMatchedHostTests {
pool := getRootCAsForHost(matchedHostTest.hostName)
// Ports have to match
pool = getRootCAsForHost("git-lfs.local:8443")
assert.Nil(t, pool)
var shouldOrShouldnt string
if matchedHostTest.shouldMatch {
shouldOrShouldnt = "should"
} else {
shouldOrShouldnt = "should not"
}
// Now use global sslcainfo
assert.Equal(t, matchedHostTest.shouldMatch, pool != nil,
"Cert lookup for \"%v\" %v have succeeded with \"%v\"",
matchedHostTest.hostName, shouldOrShouldnt, hostKey)
}
}
// Test http.sslcainfo
config.Config.ClearConfig()
config.Config.SetConfig("http.sslcainfo", tempfile.Name())
// Should match anything
pool = getRootCAsForHost("git-lfs.local")
assert.NotNil(t, pool)
pool = getRootCAsForHost("wronghost.com")
assert.NotNil(t, pool)
pool = getRootCAsForHost("git-lfs.local:8443")
assert.NotNil(t, pool)
// Should match any host at all
for _, matchedHostTest := range sslCAInfoMatchedHostTests {
pool := getRootCAsForHost(matchedHostTest.hostName)
assert.NotNil(t, pool)
}
}
@ -91,12 +111,10 @@ func TestCertFromSSLCAInfoEnv(t *testing.T) {
config.Config.SetAllEnv(map[string]string{"GIT_SSL_CAINFO": tempfile.Name()})
// Should match any host at all
pool := getRootCAsForHost("git-lfs.local")
assert.NotNil(t, pool)
pool = getRootCAsForHost("wronghost.com")
assert.NotNil(t, pool)
pool = getRootCAsForHost("notthisone.com:8888")
assert.NotNil(t, pool)
for _, matchedHostTest := range sslCAInfoMatchedHostTests {
pool := getRootCAsForHost(matchedHostTest.hostName)
assert.NotNil(t, pool)
}
}
@ -114,12 +132,10 @@ func TestCertFromSSLCAPathConfig(t *testing.T) {
config.Config.SetConfig("http.sslcapath", tempdir)
// Should match any host at all
pool := getRootCAsForHost("git-lfs.local")
assert.NotNil(t, pool)
pool = getRootCAsForHost("wronghost.com")
assert.NotNil(t, pool)
pool = getRootCAsForHost("notthisone.com:8888")
assert.NotNil(t, pool)
for _, matchedHostTest := range sslCAInfoMatchedHostTests {
pool := getRootCAsForHost(matchedHostTest.hostName)
assert.NotNil(t, pool)
}
}
@ -139,12 +155,10 @@ func TestCertFromSSLCAPathEnv(t *testing.T) {
config.Config.SetAllEnv(map[string]string{"GIT_SSL_CAPATH": tempdir})
// Should match any host at all
pool := getRootCAsForHost("git-lfs.local")
assert.NotNil(t, pool)
pool = getRootCAsForHost("wronghost.com")
assert.NotNil(t, pool)
pool = getRootCAsForHost("notthisone.com:8888")
assert.NotNil(t, pool)
for _, matchedHostTest := range sslCAInfoMatchedHostTests {
pool := getRootCAsForHost(matchedHostTest.hostName)
assert.NotNil(t, pool)
}
}