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