From 8ac48f437115875d01d59c7259d3e3f30d62a83b Mon Sep 17 00:00:00 2001 From: Christian Groschupp Date: Wed, 25 Nov 2020 21:09:38 +0100 Subject: [PATCH 1/2] add go.mod and go.sum --- go.mod | 19 +++++++++++++++++++ go.sum | 25 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 go.mod create mode 100644 go.sum diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..a85f9641 --- /dev/null +++ b/go.mod @@ -0,0 +1,19 @@ +module github.com/flashmob/go-guerrilla + +go 1.15 + +require ( + github.com/asaskevich/EventBus v0.0.0-20180103000110-68a521d7cbbb + github.com/go-sql-driver/mysql v1.4.1 + github.com/gomodule/redigo v2.0.0+incompatible + github.com/inconshreveable/mousetrap v1.0.0 + github.com/konsorten/go-windows-terminal-sequences v1.0.2 + github.com/sirupsen/logrus v1.4.2 + github.com/spf13/cobra v0.0.3 + github.com/spf13/pflag v1.0.3 + golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c + golang.org/x/sys v0.0.0-20190422165155-953cdadca894 + golang.org/x/text v0.3.2 + google.golang.org/appengine v1.5.0 + gopkg.in/iconv.v1 v1.1.1 +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..b67baf44 --- /dev/null +++ b/go.sum @@ -0,0 +1,25 @@ +github.com/asaskevich/EventBus v0.0.0-20180103000110-68a521d7cbbb/go.mod h1:JS7hed4L1fj0hXcyEejnW57/7LCetXggd+vwrRnYeII= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20180308152046-7dca6fe1f437/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +gopkg.in/iconv.v1 v1.1.1/go.mod h1:/kbQb/JfuKJjly48VfSKmiHkdA0nAzSsgDWOc3Jcb08= From 2ffe1f05c05074f7e9616c39bc3629790016f4b4 Mon Sep 17 00:00:00 2001 From: Christian Groschupp Date: Wed, 25 Nov 2020 21:10:09 +0100 Subject: [PATCH 2/2] add configurable smtp greeter --- config.go | 23 +++++++++++++++++++---- server.go | 26 +++++++++++++++++++++----- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/config.go b/config.go index b93a3026..831d6d29 100644 --- a/config.go +++ b/config.go @@ -8,6 +8,7 @@ import ( "os" "reflect" "strings" + "text/template" "time" "github.com/flashmob/go-guerrilla/backends" @@ -60,6 +61,9 @@ type ServerConfig struct { // XClientOn when using a proxy such as Nginx, XCLIENT command is used to pass the // original client's IP address & client's HELO XClientOn bool `json:"xclient_on,omitempty"` + // GreeterTemplate will be used to greet the client. + // Defaults to defaultGreeterString + GreeterTemplate *template.Template `json:"greeter_template"` } type ServerTLSConfig struct { @@ -151,10 +155,13 @@ var TLSClientAuthTypes = map[string]tls.ClientAuthType{ "RequireAndVerifyClientCert": tls.RequireAndVerifyClientCert, } -const defaultMaxClients = 100 -const defaultTimeout = 30 -const defaultInterface = "127.0.0.1:2525" -const defaultMaxSize = int64(10 << 20) // 10 Mebibytes +const ( + defaultMaxClients = 100 + defaultTimeout = 30 + defaultInterface = "127.0.0.1:2525" + defaultMaxSize = int64(10 << 20) // 10 Mebibytes + defaultGreeterString = "220 {{ .Hostname }} SMTP Guerrilla({{ .Version }}) #{{ .ClientID }} ({{ .ActiveClientsCount }}) {{ .Time }}" +) // Unmarshalls json data into AppConfig struct and any other initialization of the struct // also does validation, returns error if validation failed or something went wrong @@ -279,6 +286,10 @@ func (c *AppConfig) setDefaults() error { if err != nil { return err } + defaultGreeterTemplate, err := template.New("greeter").Parse(defaultGreeterString) + if err != nil { + return fmt.Errorf("unable to parse template: %v", err) + } if len(c.Servers) == 0 { sc := ServerConfig{} sc.LogFile = c.LogFile @@ -288,6 +299,7 @@ func (c *AppConfig) setDefaults() error { sc.MaxClients = defaultMaxClients sc.Timeout = defaultTimeout sc.MaxSize = defaultMaxSize + sc.GreeterTemplate = defaultGreeterTemplate c.Servers = append(c.Servers, sc) } else { // make sure each server has defaults correctly configured @@ -304,6 +316,9 @@ func (c *AppConfig) setDefaults() error { if c.Servers[i].MaxSize == 0 { c.Servers[i].MaxSize = defaultMaxSize // 10 Mebibytes } + if c.Servers[i].GreeterTemplate == nil { + c.Servers[i].GreeterTemplate = defaultGreeterTemplate + } if c.Servers[i].ListenInterface == "" { return fmt.Errorf("listen interface not specified for server at index %d", i) } diff --git a/server.go b/server.go index 1ab96b5b..7b988886 100644 --- a/server.go +++ b/server.go @@ -6,7 +6,6 @@ import ( "crypto/tls" "crypto/x509" "fmt" - "github.com/sirupsen/logrus" "io" "io/ioutil" "net" @@ -16,6 +15,8 @@ import ( "sync/atomic" "time" + "github.com/sirupsen/logrus" + "github.com/flashmob/go-guerrilla/backends" "github.com/flashmob/go-guerrilla/log" "github.com/flashmob/go-guerrilla/mail" @@ -66,6 +67,14 @@ type allowedHosts struct { sync.Mutex // guard access to the map } +type greeterData struct { + Hostname string + Version string + ClientID uint64 + ActiveClientsCount int + Time string +} + type command []byte var ( @@ -367,9 +376,16 @@ func (s *server) handleClient(client *client) { s.log().Infof("Handle client [%s], id: %d", client.RemoteIP, client.ID) // Initial greeting - greeting := fmt.Sprintf("220 %s SMTP Guerrilla(%s) #%d (%d) %s", - sc.Hostname, Version, client.ID, - s.clientPool.GetActiveClientsCount(), time.Now().Format(time.RFC3339)) + greeterData := greeterData{ + Hostname: sc.Hostname, + Version: Version, + ClientID: client.ID, + ActiveClientsCount: s.clientPool.GetActiveClientsCount(), + Time: time.Now().Format(time.RFC3339), + } + + var greeting bytes.Buffer + sc.GreeterTemplate.Execute(&greeting, greeterData) helo := fmt.Sprintf("250 %s Hello", sc.Hostname) // ehlo is a multi-line reply and need additional \r\n at the end @@ -404,7 +420,7 @@ func (s *server) handleClient(client *client) { for client.isAlive() { switch client.state { case ClientGreeting: - client.sendResponse(greeting) + client.sendResponse(greeting.String()) client.state = ClientCmd case ClientCmd: client.bufin.setLimit(CommandLineMaxLength)