Skip to content

Commit

Permalink
Merge pull request #907 from lluiscampos/MEN-5273-websockets-openssl-…
Browse files Browse the repository at this point in the history
…dial--websocket-fork

MEN-5273: proxy: Fix websocket connection for advanced auth settings
  • Loading branch information
lluiscampos committed Dec 13, 2021
2 parents 0a1882f + b657deb commit cac61a5
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 33 deletions.
2 changes: 1 addition & 1 deletion app/proxy/proxy_ws.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (pc *proxyControllerInner) DoWsUpgrade(w http.ResponseWriter, r *http.Reque

connBackend, resp, err := pc.wsDialer.Dial(wsUrl.String(), requestHeader)
if err != nil {
log.Errorf("couldn't dial to remote backend url %s", err)
log.Errorf("couldn't dial to remote backend url %q, err: %s", wsUrl.String(), err.Error())
if resp != nil {
// WebSocket handshake failed, reply the client with backend's resp
if err := copyResponse(w, resp); err != nil {
Expand Down
153 changes: 139 additions & 14 deletions app/proxy/proxy_ws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
package proxy

import (
"crypto/tls"
"crypto/x509"
"io/ioutil"
"net/http"
"reflect"
"runtime"
Expand All @@ -26,21 +29,33 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/mendersoftware/mender/client"
cltest "github.com/mendersoftware/mender/client/test"
"github.com/mendersoftware/mender/conf"
)

func prepareProxyWsTest(
t *testing.T,
srv *cltest.ClientTestWsServer,
) (*ProxyController, *websocket.Conn) {
func prepareProxyWsTest(t *testing.T, srv *cltest.ClientTestWsServer) *ProxyController {

wsDialer, err := client.NewWebsocketDialer(client.Config{})
require.NoError(t, err)

proxyController, err := NewProxyController(
&http.Client{},
nil,
wsDialer,
srv.TestServer.URL,
"SecretJwtToken",
)
require.NoError(t, err)

return proxyController
}

func connectProxyWsTest(
t *testing.T,
srv *cltest.ClientTestWsServer,
proxyController *ProxyController,
) *websocket.Conn {

proxyServerUrl := proxyController.GetServerUrl()
require.Contains(t, proxyServerUrl, "http://localhost")

Expand All @@ -51,14 +66,25 @@ func prepareProxyWsTest(
require.NoError(t, err)
require.Equal(t, http.StatusSwitchingProtocols, resp.StatusCode)

return proxyController, conn
return conn
}

func TestProxyWsConnect(t *testing.T) {
srv := cltest.NewClientTestWsServer()
defer srv.StopWs()
defer srv.Close()
func prepareAndConnectProxyWsTest(
t *testing.T,
srv *cltest.ClientTestWsServer,
) (*ProxyController, *websocket.Conn) {

proxyController := prepareProxyWsTest(t, srv)
conn := connectProxyWsTest(t, srv, proxyController)

return proxyController, conn
}

func runTestSendReceiveWs(
t *testing.T,
srv *cltest.ClientTestWsServer,
proxyController *ProxyController,
) {
// Expectations for the test
srv.Connect.SendMessages = append(
srv.Connect.SendMessages,
Expand All @@ -82,8 +108,8 @@ func TestProxyWsConnect(t *testing.T) {
{MsgType: websocket.TextMessage, Msg: []byte("hello-world")},
}

proxyController, conn := prepareProxyWsTest(t, srv)
defer proxyController.Stop()
conn := connectProxyWsTest(t, srv, proxyController)

defer conn.Close()

wg := sync.WaitGroup{}
Expand Down Expand Up @@ -150,6 +176,17 @@ func TestProxyWsConnect(t *testing.T) {
)
}

func TestProxyWsConnect(t *testing.T) {
srv := cltest.NewClientTestWsServer()
defer srv.StopWs()
defer srv.Close()

proxyController := prepareProxyWsTest(t, srv)
defer proxyController.Stop()

runTestSendReceiveWs(t, srv, proxyController)
}

func TestProxyWsWebSocketProtocolHeader(t *testing.T) {
srv := cltest.NewClientTestWsServer()
defer srv.StopWs()
Expand Down Expand Up @@ -195,7 +232,7 @@ func TestProxyWsTooMany(t *testing.T) {
defer srv.StopWs()
defer srv.Close()

proxyController, conn := prepareProxyWsTest(t, srv)
proxyController, conn := prepareAndConnectProxyWsTest(t, srv)
defer proxyController.Stop()
defer conn.Close()

Expand All @@ -218,7 +255,7 @@ func TestProxyWsStop(t *testing.T) {
defer srv.StopWs()
defer srv.Close()

proxyController, conn := prepareProxyWsTest(t, srv)
proxyController, conn := prepareAndConnectProxyWsTest(t, srv)
defer proxyController.Stop()
defer conn.Close()

Expand Down Expand Up @@ -309,3 +346,91 @@ func TestProxyWsGoroutines(t *testing.T) {
1*time.Millisecond,
)
}

func TestProxyWsConnectCustomCert(t *testing.T) {
serverCert, err := tls.LoadX509KeyPair(
"../../client/test/server.crt",
"../../client/test/server.key",
)
require.NoError(t, err)

tc := tls.Config{
Certificates: []tls.Certificate{serverCert},
}

srv := cltest.NewClientTestWsServer(&tc)
defer srv.StopWs()
defer srv.Close()

conffromfile := conf.MenderConfigFromFile{
ServerCertificate: "../../client/test/server.crt",
}
testconf := &conf.MenderConfig{MenderConfigFromFile: conffromfile}
httpConfig := testconf.GetHttpConfig()

api, err := client.New(httpConfig)
require.NoError(t, err)

wsDialer, err := client.NewWebsocketDialer(httpConfig)
require.NoError(t, err)

proxyController, err := NewProxyController(
api,
wsDialer,
srv.TestServer.URL,
"SecretJwtToken",
)
require.NoError(t, err)
defer proxyController.Stop()

runTestSendReceiveWs(t, srv, proxyController)
}
func TestProxyWsConnectMutualTLS(t *testing.T) {
serverCert, err := tls.LoadX509KeyPair(
"../../client/test/server.crt",
"../../client/test/server.key",
)
require.NoError(t, err)

clientClientCertPool := x509.NewCertPool()
pb, err := ioutil.ReadFile("../../client/testdata/client.crt")
require.NoError(t, err)
clientClientCertPool.AppendCertsFromPEM(pb)

tc := tls.Config{
Certificates: []tls.Certificate{serverCert},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: clientClientCertPool,
}

srv := cltest.NewClientTestWsServer(&tc)
defer srv.StopWs()
defer srv.Close()

conffromfile := conf.MenderConfigFromFile{
ServerCertificate: "../../client/test/server.crt",
HttpsClient: client.HttpsClient{
Certificate: "../../client/testdata/client.crt",
Key: "../../client/testdata/client-cert.key",
},
}
testconf := &conf.MenderConfig{MenderConfigFromFile: conffromfile}
httpConfig := testconf.GetHttpConfig()

api, err := client.New(httpConfig)
require.NoError(t, err)

wsDialer, err := client.NewWebsocketDialer(httpConfig)
require.NoError(t, err)

proxyController, err := NewProxyController(
api,
wsDialer,
srv.TestServer.URL,
"SecretJwtToken",
)
require.NoError(t, err)
defer proxyController.Stop()

runTestSendReceiveWs(t, srv, proxyController)
}
5 changes: 2 additions & 3 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,7 @@ func loadClientTrust(ctx *openssl.Ctx, conf *Config) (*openssl.Ctx, error) {
return ctx, nil
}

func dialOpenSSL(ctx *openssl.Ctx, conf *Config, network string, addr string) (net.Conn, error) {

func dialOpenSSL(ctx *openssl.Ctx, conf *Config, _ string, addr string) (net.Conn, error) {
flags := openssl.DialFlags(0)

if conf.NoVerify {
Expand Down Expand Up @@ -694,7 +693,7 @@ func newWebsocketDialerTLS(conf Config) (*websocket.Dialer, error) {
}

dialer := websocket.Dialer{
NetDial: func(network string, addr string) (net.Conn, error) {
NetDialTLS: func(network string, addr string) (net.Conn, error) {
return dialOpenSSL(ctx, &conf, network, addr)
},
}
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ require (
)

replace github.com/urfave/cli/v2 => github.com/mendersoftware/cli/v2 v2.1.1-minimal

replace github.com/gorilla/websocket => github.com/mendersoftware/websocket v1.4.3-0.20211210145825-8a45e5d03918
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4=
github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/klauspost/compress v1.10.5 h1:7q6vHIqubShURwQz8cQK6yIe/xC3IF0Vm7TGfqjewrc=
github.com/klauspost/compress v1.10.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
Expand All @@ -34,6 +32,8 @@ github.com/mendersoftware/openssl v1.1.0 h1:eRiG3CwzkMIna1xrTE9SiX9lrsme9irlb6i5
github.com/mendersoftware/openssl v1.1.0/go.mod h1:tikEC94q+Y0TU6r19L6mHzwruoTNYPEkrQPvsHEcQyU=
github.com/mendersoftware/progressbar v0.0.3 h1:AUdBGPvXO0l9i39rmXKZbEAPet2FzBeiG8b30D5/2Vc=
github.com/mendersoftware/progressbar v0.0.3/go.mod h1:NYaLNLhy3UXkRweGjhR3We3Q1ngmUmOWjC3+m8EzwjE=
github.com/mendersoftware/websocket v1.4.3-0.20211210145825-8a45e5d03918 h1:bxs2j1011PQiBPAP127cmBdAnw+zzq65tWOUeCFxVXU=
github.com/mendersoftware/websocket v1.4.3-0.20211210145825-8a45e5d03918/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
Expand Down
58 changes: 48 additions & 10 deletions vendor/github.com/gorilla/websocket/client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions vendor/github.com/gorilla/websocket/client_clone.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions vendor/github.com/gorilla/websocket/client_clone_legacy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions vendor/github.com/gorilla/websocket/conn_write.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions vendor/github.com/gorilla/websocket/conn_write_legacy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit cac61a5

Please sign in to comment.