Do not verify certificate when using --insecure-registry on an HTTPS registry

Signed-off-by: Tibor Vass <teabee89@gmail.com>

Conflicts:
	registry/registry.go
	registry/registry_test.go
	registry/service.go
	registry/session.go
This commit is contained in:
Tibor Vass 2014-10-10 23:22:12 -04:00
parent 27ddc260e2
commit 798fd3c764
5 changed files with 101 additions and 100 deletions

View file

@ -14,6 +14,7 @@ import (
"strings"
"time"
"github.com/docker/docker/pkg/log"
"github.com/docker/docker/utils"
)
@ -35,13 +36,17 @@ const (
ConnectTimeout
)
func newClient(jar http.CookieJar, roots *x509.CertPool, cert *tls.Certificate, timeout TimeoutType) *http.Client {
func newClient(jar http.CookieJar, roots *x509.CertPool, cert *tls.Certificate, timeout TimeoutType, secure bool) *http.Client {
tlsConfig := tls.Config{RootCAs: roots}
if cert != nil {
tlsConfig.Certificates = append(tlsConfig.Certificates, *cert)
}
if !secure {
tlsConfig.InsecureSkipVerify = true
}
httpTransport := &http.Transport{
DisableKeepAlives: true,
Proxy: http.ProxyFromEnvironment,
@ -78,69 +83,76 @@ func newClient(jar http.CookieJar, roots *x509.CertPool, cert *tls.Certificate,
}
}
func doRequest(req *http.Request, jar http.CookieJar, timeout TimeoutType) (*http.Response, *http.Client, error) {
hasFile := func(files []os.FileInfo, name string) bool {
for _, f := range files {
if f.Name() == name {
return true
}
}
return false
}
hostDir := path.Join("/etc/docker/certs.d", req.URL.Host)
fs, err := ioutil.ReadDir(hostDir)
if err != nil && !os.IsNotExist(err) {
return nil, nil, err
}
func doRequest(req *http.Request, jar http.CookieJar, timeout TimeoutType, secure bool) (*http.Response, *http.Client, error) {
var (
pool *x509.CertPool
certs []*tls.Certificate
)
for _, f := range fs {
if strings.HasSuffix(f.Name(), ".crt") {
if pool == nil {
pool = x509.NewCertPool()
if secure && req.URL.Scheme == "https" {
hasFile := func(files []os.FileInfo, name string) bool {
for _, f := range files {
if f.Name() == name {
return true
}
}
data, err := ioutil.ReadFile(path.Join(hostDir, f.Name()))
if err != nil {
return nil, nil, err
}
pool.AppendCertsFromPEM(data)
return false
}
if strings.HasSuffix(f.Name(), ".cert") {
certName := f.Name()
keyName := certName[:len(certName)-5] + ".key"
if !hasFile(fs, keyName) {
return nil, nil, fmt.Errorf("Missing key %s for certificate %s", keyName, certName)
}
cert, err := tls.LoadX509KeyPair(path.Join(hostDir, certName), path.Join(hostDir, keyName))
if err != nil {
return nil, nil, err
}
certs = append(certs, &cert)
hostDir := path.Join("/etc/docker/certs.d", req.URL.Host)
log.Debugf("hostDir: %s", hostDir)
fs, err := ioutil.ReadDir(hostDir)
if err != nil && !os.IsNotExist(err) {
return nil, nil, err
}
if strings.HasSuffix(f.Name(), ".key") {
keyName := f.Name()
certName := keyName[:len(keyName)-4] + ".cert"
if !hasFile(fs, certName) {
return nil, nil, fmt.Errorf("Missing certificate %s for key %s", certName, keyName)
for _, f := range fs {
if strings.HasSuffix(f.Name(), ".crt") {
if pool == nil {
pool = x509.NewCertPool()
}
log.Debugf("crt: %s", hostDir+"/"+f.Name())
data, err := ioutil.ReadFile(path.Join(hostDir, f.Name()))
if err != nil {
return nil, nil, err
}
pool.AppendCertsFromPEM(data)
}
if strings.HasSuffix(f.Name(), ".cert") {
certName := f.Name()
keyName := certName[:len(certName)-5] + ".key"
log.Debugf("cert: %s", hostDir+"/"+f.Name())
if !hasFile(fs, keyName) {
return nil, nil, fmt.Errorf("Missing key %s for certificate %s", keyName, certName)
}
cert, err := tls.LoadX509KeyPair(path.Join(hostDir, certName), path.Join(hostDir, keyName))
if err != nil {
return nil, nil, err
}
certs = append(certs, &cert)
}
if strings.HasSuffix(f.Name(), ".key") {
keyName := f.Name()
certName := keyName[:len(keyName)-4] + ".cert"
log.Debugf("key: %s", hostDir+"/"+f.Name())
if !hasFile(fs, certName) {
return nil, nil, fmt.Errorf("Missing certificate %s for key %s", certName, keyName)
}
}
}
}
if len(certs) == 0 {
client := newClient(jar, pool, nil, timeout)
client := newClient(jar, pool, nil, timeout, secure)
res, err := client.Do(req)
if err != nil {
return nil, nil, err
}
return res, client, nil
}
for i, cert := range certs {
client := newClient(jar, pool, cert, timeout)
client := newClient(jar, pool, cert, timeout, secure)
res, err := client.Do(req)
// If this is the last cert, otherwise, continue to next cert if 403 or 5xx
if i == len(certs)-1 || err == nil && res.StatusCode != 403 && res.StatusCode < 500 {
@ -202,49 +214,6 @@ func ResolveRepositoryName(reposName string) (string, string, error) {
return hostname, reposName, nil
}
// this method expands the registry name as used in the prefix of a repo
// to a full url. if it already is a url, there will be no change.
func ExpandAndVerifyRegistryUrl(hostname string, secure bool) (string, error) {
if hostname == IndexServerAddress() {
return hostname, nil
}
endpoint := fmt.Sprintf("http://%s/v1/", hostname)
if secure {
endpoint = fmt.Sprintf("https://%s/v1/", hostname)
}
if _, oerr := pingRegistryEndpoint(endpoint); oerr != nil {
//TODO: triggering highland build can be done there without "failing"
err := fmt.Errorf("Invalid registry endpoint '%s': %s ", endpoint, oerr)
if secure {
err = fmt.Errorf("%s. If this private registry supports only HTTP, please add `--insecure-registry %s` to the daemon's arguments.", oerr, hostname)
}
return "", err
}
return endpoint, nil
}
// this method verifies if the provided hostname is part of the list of
// insecure registries and returns false if HTTP should be used
func IsSecure(hostname string, insecureRegistries []string) bool {
if hostname == IndexServerAddress() {
return true
}
for _, h := range insecureRegistries {
if hostname == h {
return false
}
}
return true
}
func trustedLocation(req *http.Request) bool {
var (
trusteds = []string{"docker.com", "docker.io"}