gopkg.in/openshift/source-to-image.v1@v1.2.0/test/integration/docker/dockerssl_test.go (about)

     1  // +build integration
     2  
     3  package docker
     4  
     5  import (
     6  	"crypto/tls"
     7  	"crypto/x509"
     8  	"io/ioutil"
     9  	"log"
    10  	"net"
    11  	"net/http"
    12  	"os"
    13  	"runtime"
    14  	"testing"
    15  
    16  	"github.com/openshift/source-to-image/pkg/api"
    17  	"github.com/openshift/source-to-image/pkg/docker"
    18  )
    19  
    20  const (
    21  	tcpListener  = "127.0.0.1:8080"
    22  	tlsListener  = "127.0.0.1:8443"
    23  	unixListener = "/tmp/test.sock"
    24  )
    25  
    26  var serverCert tls.Certificate
    27  var caPool *x509.CertPool
    28  
    29  func init() {
    30  	var err error
    31  	serverCert, err = tls.LoadX509KeyPair("../testdata/127.0.0.1.crt", "../testdata/127.0.0.1.key")
    32  	if err != nil {
    33  		panic(err)
    34  	}
    35  
    36  	ca, err := ioutil.ReadFile("../testdata/ca.crt")
    37  	if err != nil {
    38  		panic(err)
    39  	}
    40  
    41  	caPool = x509.NewCertPool()
    42  	caPool.AppendCertsFromPEM(ca)
    43  
    44  	log.SetOutput(ioutil.Discard)
    45  }
    46  
    47  type Server struct {
    48  	l net.Listener
    49  	c chan struct{}
    50  }
    51  
    52  func (s *Server) Close() {
    53  	s.l.Close()
    54  	<-s.c
    55  }
    56  
    57  func (s *Server) serveFakeDockerAPIServer() {
    58  	mux := http.NewServeMux()
    59  	mux.HandleFunc("/version", func(w http.ResponseWriter, req *http.Request) {
    60  		w.Header().Add("Content-Type", "application/json")
    61  		w.Write([]byte("{}"))
    62  	})
    63  	hs := http.Server{Handler: mux}
    64  	// Disable keepalives in order to prevent an explosion in the number of
    65  	// goroutines that makes stack traces noisy.  TODO: when using Go 1.8,
    66  	// http.Server.Shutdown() should do this for us.
    67  	hs.SetKeepAlivesEnabled(false)
    68  	hs.Serve(s.l)
    69  	s.c <- struct{}{}
    70  }
    71  
    72  func serveTLS(t *testing.T, config *tls.Config) *Server {
    73  	config.Certificates = []tls.Certificate{serverCert}
    74  
    75  	l, err := tls.Listen("tcp", tlsListener, config)
    76  	if err != nil {
    77  		t.Fatal(err)
    78  	}
    79  
    80  	s := &Server{l: l, c: make(chan struct{})}
    81  	go s.serveFakeDockerAPIServer()
    82  
    83  	return s
    84  }
    85  
    86  func serveTCP(t *testing.T) *Server {
    87  	l, err := net.Listen("tcp", tcpListener)
    88  	if err != nil {
    89  		t.Fatal(err)
    90  	}
    91  
    92  	s := &Server{l: l, c: make(chan struct{})}
    93  	go s.serveFakeDockerAPIServer()
    94  
    95  	return s
    96  }
    97  
    98  func serveUNIX(t *testing.T) *Server {
    99  	os.Remove(unixListener)
   100  
   101  	l, err := net.Listen("unix", unixListener)
   102  	if err != nil {
   103  		t.Fatal(err)
   104  	}
   105  
   106  	s := &Server{l: l, c: make(chan struct{})}
   107  	go s.serveFakeDockerAPIServer()
   108  
   109  	return s
   110  }
   111  
   112  func runTest(t *testing.T, config *api.DockerConfig, expectedSuccess bool) {
   113  	client, err := docker.NewEngineAPIClient(config)
   114  	if err != nil {
   115  		if expectedSuccess {
   116  			t.Errorf("with DockerConfig %+v, expected success %v, got error %v", config, expectedSuccess, err)
   117  		}
   118  		return
   119  	}
   120  	d := docker.New(client, api.AuthConfig{})
   121  	err = d.CheckReachable()
   122  	if (err == nil) != expectedSuccess {
   123  		t.Errorf("with DockerConfig %+v, expected success %v, got error %v", config, expectedSuccess, err)
   124  	}
   125  }
   126  
   127  func TestTCP(t *testing.T) {
   128  	s := serveTCP(t)
   129  	defer s.Close()
   130  
   131  	dc := &api.DockerConfig{Endpoint: "tcp://" + tcpListener}
   132  
   133  	for _, dc.UseTLS = range []bool{true, false} {
   134  		for _, dc.TLSVerify = range []bool{true, false} {
   135  			for _, dc.CAFile = range []string{"../testdata/ca.crt", "bad", ""} {
   136  				for _, dc.CertFile = range []string{"../testdata/client.crt", "bad", ""} {
   137  					for _, dc.KeyFile = range []string{"../testdata/client.key", "bad", ""} {
   138  						runTest(t, dc, !dc.UseTLS && !dc.TLSVerify)
   139  					}
   140  				}
   141  			}
   142  		}
   143  	}
   144  }
   145  
   146  func TestUNIX(t *testing.T) {
   147  	if runtime.GOOS == "windows" {
   148  		return
   149  	}
   150  
   151  	s := serveUNIX(t)
   152  	defer s.Close()
   153  
   154  	dc := &api.DockerConfig{Endpoint: "unix://" + unixListener}
   155  
   156  	for _, dc.UseTLS = range []bool{true, false} {
   157  		for _, dc.TLSVerify = range []bool{true, false} {
   158  			for _, dc.CAFile = range []string{"../testdata/ca.crt", "bad", ""} {
   159  				for _, dc.CertFile = range []string{"../testdata/client.crt", "bad", ""} {
   160  					for _, dc.KeyFile = range []string{"../testdata/client.key", "bad", ""} {
   161  						runTest(t, dc, !dc.UseTLS && !dc.TLSVerify)
   162  					}
   163  				}
   164  			}
   165  		}
   166  	}
   167  }
   168  
   169  func TestSSL(t *testing.T) {
   170  	s := serveTLS(t, &tls.Config{})
   171  	defer s.Close()
   172  
   173  	dc := &api.DockerConfig{Endpoint: "tcp://" + tlsListener}
   174  
   175  	for _, dc.UseTLS = range []bool{true, false} {
   176  		for _, dc.TLSVerify = range []bool{true, false} {
   177  			for _, dc.CAFile = range []string{"../testdata/ca.crt", "bad", ""} {
   178  				for _, dc.CertFile = range []string{"../testdata/client.crt", "bad", ""} {
   179  					for _, dc.KeyFile = range []string{"../testdata/client.key", "bad", ""} {
   180  						expected := dc.UseTLS && !dc.TLSVerify || dc.TLSVerify && dc.CAFile == "../testdata/ca.crt"
   181  
   182  						if (dc.CertFile == "../testdata/client.crt") != (dc.KeyFile == "../testdata/client.key") {
   183  							expected = false
   184  						}
   185  
   186  						runTest(t, dc, expected)
   187  					}
   188  				}
   189  			}
   190  		}
   191  	}
   192  }
   193  
   194  func TestSSLClientCert(t *testing.T) {
   195  	s := serveTLS(t, &tls.Config{
   196  		ClientAuth: tls.RequireAndVerifyClientCert,
   197  		ClientCAs:  caPool,
   198  	})
   199  	defer s.Close()
   200  
   201  	dc := &api.DockerConfig{Endpoint: "tcp://" + tlsListener}
   202  
   203  	for _, dc.UseTLS = range []bool{true, false} {
   204  		for _, dc.TLSVerify = range []bool{true, false} {
   205  			for _, dc.CAFile = range []string{"../testdata/ca.crt", "bad", ""} {
   206  				for _, dc.CertFile = range []string{"../testdata/client.crt", "bad", ""} {
   207  					for _, dc.KeyFile = range []string{"../testdata/client.key", "bad", ""} {
   208  						expected := dc.UseTLS && !dc.TLSVerify || dc.TLSVerify && dc.CAFile == "../testdata/ca.crt"
   209  
   210  						if dc.CertFile != "../testdata/client.crt" || dc.KeyFile != "../testdata/client.key" {
   211  							expected = false
   212  						}
   213  
   214  						runTest(t, dc, expected)
   215  					}
   216  				}
   217  			}
   218  		}
   219  	}
   220  }