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 }