github.com/squaremo/docker@v1.3.2-0.20150516120342-42cfc9554972/api/server/tcp_socket.go (about)

     1  package server
     2  
     3  import (
     4  	"crypto/tls"
     5  	"crypto/x509"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net"
     9  	"os"
    10  
    11  	"github.com/docker/docker/pkg/listenbuffer"
    12  )
    13  
    14  type tlsConfig struct {
    15  	CA          string
    16  	Certificate string
    17  	Key         string
    18  	Verify      bool
    19  }
    20  
    21  func tlsConfigFromServerConfig(conf *ServerConfig) *tlsConfig {
    22  	verify := conf.TlsVerify
    23  	if !conf.Tls && !conf.TlsVerify {
    24  		return nil
    25  	}
    26  	return &tlsConfig{
    27  		Verify:      verify,
    28  		Certificate: conf.TlsCert,
    29  		Key:         conf.TlsKey,
    30  		CA:          conf.TlsCa,
    31  	}
    32  }
    33  
    34  func NewTcpSocket(addr string, config *tlsConfig, activate <-chan struct{}) (net.Listener, error) {
    35  	l, err := listenbuffer.NewListenBuffer("tcp", addr, activate)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  	if config != nil {
    40  		if l, err = setupTls(l, config); err != nil {
    41  			return nil, err
    42  		}
    43  	}
    44  	return l, nil
    45  }
    46  
    47  func setupTls(l net.Listener, config *tlsConfig) (net.Listener, error) {
    48  	tlsCert, err := tls.LoadX509KeyPair(config.Certificate, config.Key)
    49  	if err != nil {
    50  		if os.IsNotExist(err) {
    51  			return nil, fmt.Errorf("Could not load X509 key pair (%s, %s): %v", config.Certificate, config.Key, err)
    52  		}
    53  		return nil, fmt.Errorf("Error reading X509 key pair (%s, %s): %q. Make sure the key is encrypted.",
    54  			config.Certificate, config.Key, err)
    55  	}
    56  	tlsConfig := &tls.Config{
    57  		NextProtos:   []string{"http/1.1"},
    58  		Certificates: []tls.Certificate{tlsCert},
    59  		// Avoid fallback on insecure SSL protocols
    60  		MinVersion: tls.VersionTLS10,
    61  	}
    62  	if config.CA != "" {
    63  		certPool := x509.NewCertPool()
    64  		file, err := ioutil.ReadFile(config.CA)
    65  		if err != nil {
    66  			return nil, fmt.Errorf("Could not read CA certificate: %v", err)
    67  		}
    68  		certPool.AppendCertsFromPEM(file)
    69  		tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
    70  		tlsConfig.ClientCAs = certPool
    71  	}
    72  	return tls.NewListener(l, tlsConfig), nil
    73  }