From 26dc5024e323647a9280772b5e0c115eb0ed34f9 Mon Sep 17 00:00:00 2001 From: Endre Kovacs Date: Thu, 29 Aug 2024 10:48:36 +0200 Subject: [PATCH 1/4] allow the clients of acceptor to specify their own tls.Config --- accepter_test.go | 43 +++++++++++++++++++++++++++++++++++++++++++ acceptor.go | 25 ++++++++++++++++++++----- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/accepter_test.go b/accepter_test.go index 54bfff845..413bf9e21 100644 --- a/accepter_test.go +++ b/accepter_test.go @@ -16,6 +16,7 @@ package quickfix import ( + "crypto/tls" "net" "testing" @@ -23,6 +24,7 @@ import ( proxyproto "github.com/pires/go-proxyproto" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestAcceptor_Start(t *testing.T) { @@ -83,3 +85,44 @@ func TestAcceptor_Start(t *testing.T) { }) } } + +func TestAcceptor_SetTLSConfig(t *testing.T) { + sessionSettings := NewSessionSettings() + sessionSettings.Set(config.BeginString, BeginStringFIX42) + sessionSettings.Set(config.SenderCompID, "sender") + sessionSettings.Set(config.TargetCompID, "target") + + genericSettings := NewSettings() + + genericSettings.GlobalSettings().Set("SocketAcceptPort", "5001") + _, err := genericSettings.AddSession(sessionSettings) + require.NoError(t, err) + + logger, err := NewScreenLogFactory().Create() + require.NoError(t, err) + acceptor := &Acceptor{settings: genericSettings, globalLog: logger} + defer acceptor.Stop() + // example of a customized tls.Config that loads the certificates dynamically by the `GetCertificate` function + // as opposed to the Certificates slice, that is static in nature, and is only populated once and needs application restart to reload the certs. + customizedTLSConfig := tls.Config{ + Certificates: []tls.Certificate{}, + GetCertificate: func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) { + cert, err := tls.LoadX509KeyPair("_test_data/localhost.crt", "_test_data/localhost.key") + if err != nil { + return nil, err + } + return &cert, nil + }, + } + + acceptor.SetTLSConfig(&customizedTLSConfig) + assert.NoError(t, acceptor.Start()) + assert.Len(t, acceptor.listeners, 1) + + conn, err := tls.Dial("tcp", "localhost:5001", &tls.Config{ + InsecureSkipVerify: true, + }) + require.NoError(t, err) + assert.NotNil(t, conn) + defer conn.Close() +} diff --git a/acceptor.go b/acceptor.go index f5b9b281c..6bea76bdc 100644 --- a/acceptor.go +++ b/acceptor.go @@ -19,6 +19,7 @@ import ( "bufio" "bytes" "crypto/tls" + "fmt" "io" "net" "runtime/debug" @@ -48,6 +49,7 @@ type Acceptor struct { sessionHostPort map[SessionID]int listeners map[string]net.Listener connectionValidator ConnectionValidator + tlsConfig *tls.Config sessionFactory } @@ -81,9 +83,12 @@ func (a *Acceptor) Start() (err error) { a.listeners[address] = nil } - var tlsConfig *tls.Config - if tlsConfig, err = loadTLSConfig(a.settings.GlobalSettings()); err != nil { - return + if a.tlsConfig == nil { + var tlsConfig *tls.Config + if tlsConfig, err = loadTLSConfig(a.settings.GlobalSettings()); err != nil { + return + } + a.tlsConfig = tlsConfig } var useTCPProxy bool @@ -94,8 +99,8 @@ func (a *Acceptor) Start() (err error) { } for address := range a.listeners { - if tlsConfig != nil { - if a.listeners[address], err = tls.Listen("tcp", address, tlsConfig); err != nil { + if a.tlsConfig != nil { + if a.listeners[address], err = tls.Listen("tcp", address, a.tlsConfig); err != nil { return } } else if a.listeners[address], err = net.Listen("tcp", address); err != nil { @@ -228,6 +233,7 @@ func (a *Acceptor) invalidMessage(msg *bytes.Buffer, err error) { func (a *Acceptor) handleConnection(netConn net.Conn) { defer func() { if err := recover(); err != nil { + fmt.Println("asdqwe", a.globalLog) a.globalLog.OnEventf("Connection Terminated with Panic: %s", debug.Stack()) } @@ -421,3 +427,12 @@ LOOP: func (a *Acceptor) SetConnectionValidator(validator ConnectionValidator) { a.connectionValidator = validator } + +// SetTLSConfig allows the creator of the Acceptor to specify a fully customizable tls.Config. + +// When the caller explicitly provides a tls.Config with this function, +// it takes precendent over TLS settings specified in the acceptor's settings.GlobalSettings(), +// meaning that the setting object is not inspected or used for the creation of the tls.Config. +func (a *Acceptor) SetTLSConfig(tlsConfig *tls.Config) { + a.tlsConfig = tlsConfig +} From aa3199175a62f75ca869b6ac2c90173debcfff74 Mon Sep 17 00:00:00 2001 From: Endre Kovacs Date: Thu, 29 Aug 2024 11:24:03 +0200 Subject: [PATCH 2/4] lint fix --- accepter_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accepter_test.go b/accepter_test.go index 413bf9e21..5cf888a8c 100644 --- a/accepter_test.go +++ b/accepter_test.go @@ -106,7 +106,7 @@ func TestAcceptor_SetTLSConfig(t *testing.T) { // as opposed to the Certificates slice, that is static in nature, and is only populated once and needs application restart to reload the certs. customizedTLSConfig := tls.Config{ Certificates: []tls.Certificate{}, - GetCertificate: func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) { + GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) { cert, err := tls.LoadX509KeyPair("_test_data/localhost.crt", "_test_data/localhost.key") if err != nil { return nil, err From 6e397eeff979c9f5973e7c476c6cd4d5b1133b6d Mon Sep 17 00:00:00 2001 From: Endre Kovacs Date: Thu, 29 Aug 2024 13:54:58 +0200 Subject: [PATCH 3/4] cleanup --- acceptor.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/acceptor.go b/acceptor.go index 6bea76bdc..c391b62af 100644 --- a/acceptor.go +++ b/acceptor.go @@ -19,7 +19,6 @@ import ( "bufio" "bytes" "crypto/tls" - "fmt" "io" "net" "runtime/debug" @@ -233,7 +232,6 @@ func (a *Acceptor) invalidMessage(msg *bytes.Buffer, err error) { func (a *Acceptor) handleConnection(netConn net.Conn) { defer func() { if err := recover(); err != nil { - fmt.Println("asdqwe", a.globalLog) a.globalLog.OnEventf("Connection Terminated with Panic: %s", debug.Stack()) } From f4d6fe9276e8081ac8dc27764e427db58c4c670d Mon Sep 17 00:00:00 2001 From: Endre Kovacs Date: Thu, 29 Aug 2024 14:11:18 +0200 Subject: [PATCH 4/4] adjust comments --- acceptor.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/acceptor.go b/acceptor.go index c391b62af..2f9f6c48b 100644 --- a/acceptor.go +++ b/acceptor.go @@ -426,11 +426,12 @@ func (a *Acceptor) SetConnectionValidator(validator ConnectionValidator) { a.connectionValidator = validator } -// SetTLSConfig allows the creator of the Acceptor to specify a fully customizable tls.Config. - -// When the caller explicitly provides a tls.Config with this function, +// SetTLSConfig allows the creator of the Acceptor to specify a fully customizable tls.Config of their choice, +// which will be used in the Start() method. +// +// Note: when the caller explicitly provides a tls.Config with this function, // it takes precendent over TLS settings specified in the acceptor's settings.GlobalSettings(), -// meaning that the setting object is not inspected or used for the creation of the tls.Config. +// meaning that the `settings.GlobalSettings()` object is not inspected or used for the creation of the tls.Config. func (a *Acceptor) SetTLSConfig(tlsConfig *tls.Config) { a.tlsConfig = tlsConfig }