switch to better supported go-guerilla lib

This commit is contained in:
wiggin77
2025-05-24 22:59:23 -04:00
parent 7dfc360320
commit 5bbf1b4d4a
11 changed files with 154 additions and 125 deletions

View File

@ -38,11 +38,11 @@ func TestLoginAuthNext(t *testing.T) {
}
tests := []struct {
name string
serverMsg string
more bool
expected string
expectErr bool
name string
serverMsg string
more bool
expected string
expectErr bool
}{
{
name: "username prompt - User Name",

View File

@ -10,7 +10,7 @@ import (
"net/textproto"
"strconv"
"github.com/flashmob/go-guerrilla/mail"
"github.com/phires/go-guerrilla/mail"
"github.com/pkg/errors"
)
@ -41,6 +41,9 @@ func sendMail(e *mail.Envelope, config *relayConfig) error {
}
tlsconfig := &tls.Config{
// InsecureSkipVerify is configurable to support legacy SMTP servers with
// self-signed certificates or hostname mismatches. This should only be
// enabled in trusted network environments.
InsecureSkipVerify: config.SkipVerify, //nolint:gosec
ServerName: config.Server,
}

View File

@ -4,7 +4,7 @@ import (
"net/textproto"
"testing"
"github.com/flashmob/go-guerrilla/mail"
"github.com/phires/go-guerrilla/mail"
"github.com/stretchr/testify/assert"
)

View File

@ -11,7 +11,7 @@ func TestConfigDefaults(t *testing.T) {
var cfg mailRelayConfig
configDefaults(&cfg)
assert.Equal(t, DefaultSTMPPort, cfg.SMTPPort)
assert.Equal(t, DefaultSMTPPort, cfg.SMTPPort)
assert.Equal(t, false, cfg.SMTPStartTLS)
assert.Equal(t, false, cfg.SMTPLoginAuthType)
assert.Equal(t, int64(DefaultMaxEmailSize), cfg.MaxEmailSize)
@ -56,7 +56,7 @@ func TestLoadConfig(t *testing.T) {
assert.Equal(t, "user@minimal.com", cfg.SMTPUsername)
assert.Equal(t, "password", cfg.SMTPPassword)
// Check that defaults are applied
assert.Equal(t, DefaultSTMPPort, cfg.SMTPPort)
assert.Equal(t, DefaultSMTPPort, cfg.SMTPPort)
assert.Equal(t, DefaultLocalListenIP, cfg.LocalListenIP)
assert.Equal(t, DefaultLocalListenPort, cfg.LocalListenPort)
assert.Equal(t, []string{"*"}, cfg.AllowedHosts)

15
go.mod
View File

@ -3,21 +3,20 @@ module github.com/wiggin77/mailrelay
go 1.23.8
require (
github.com/flashmob/go-guerrilla v1.6.1
github.com/jpillora/ipfilter v1.2.2
github.com/phires/go-guerrilla v1.6.7
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.5.1
github.com/stretchr/testify v1.10.0
)
require (
github.com/asaskevich/EventBus v0.0.0-20180103000110-68a521d7cbbb // indirect
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-sql-driver/mysql v1.5.0 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
github.com/phuslu/iploc v1.0.20200807 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.6.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce // indirect
golang.org/x/sys v0.1.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
golang.org/x/crypto v0.36.0 // indirect
golang.org/x/sys v0.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

39
go.sum
View File

@ -1,36 +1,39 @@
github.com/asaskevich/EventBus v0.0.0-20180103000110-68a521d7cbbb h1:UgErHX+sTKfxJ1+2IksfX2Jeb2DcSgWN0oqRTUzSg74=
github.com/asaskevich/EventBus v0.0.0-20180103000110-68a521d7cbbb/go.mod h1:JS7hed4L1fj0hXcyEejnW57/7LCetXggd+vwrRnYeII=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef h1:2JGTg6JapxP9/R33ZaagQtAM4EkkSYnIAlOG5EI8gkM=
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef/go.mod h1:JS7hed4L1fj0hXcyEejnW57/7LCetXggd+vwrRnYeII=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/flashmob/go-guerrilla v1.6.1 h1:MLkqzRFUJveVAWuQ3s2MNPTAWbvXLt8EFsBoraS6qHA=
github.com/flashmob/go-guerrilla v1.6.1/go.mod h1:ZT9TRggRsSY4ZVndoyx8TRUxi3tM/nOYtKWKDX94H0I=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/jpillora/ipfilter v1.2.2 h1:lfENG7V1/T+ZutAtSbt6gssvzj3Ql0JmcFlqS/BES2E=
github.com/jpillora/ipfilter v1.2.2/go.mod h1:xvAYjA+48eM9E5+sg9yI55N5lE9sefckjsnDvSiEA+g=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/phires/go-guerrilla v1.6.7 h1:RkhvR4YjwZerwjwRzl3JaiPtWzDeiBM96ZADYlS3Hdc=
github.com/phires/go-guerrilla v1.6.7/go.mod h1:oR46MI4t2spk8BdaHcN7hgq6Rz6LpAHz8HHMMxegNS4=
github.com/phuslu/iploc v1.0.20200807 h1:LIBm2Y9l5zmUvnJhQgMcLZ0iVwuG+5/L6AgbMwSOpE4=
github.com/phuslu/iploc v1.0.20200807/go.mod h1:Q/0VX0txvbxekt4NhWIi3Q3eyZ139lHhnlzvDxyXhuc=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc=
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -5,9 +5,9 @@ import (
"testing"
"time"
"github.com/flashmob/go-guerrilla/log"
"github.com/flashmob/go-guerrilla/mail"
"github.com/jpillora/ipfilter"
"github.com/phires/go-guerrilla/log"
"github.com/phires/go-guerrilla/mail"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -260,9 +260,9 @@ func TestSendMail_IPFiltering_Allowed(t *testing.T) {
func TestSendMail_ServerErrors(t *testing.T) {
setupTestLogger(t)
tests := []struct {
name string
failCommand string
expectError string
name string
failCommand string
expectError string
}{
{
name: "MAIL command fails",

52
main.go
View File

@ -11,12 +11,12 @@ import (
"os/signal"
"syscall"
log "github.com/flashmob/go-guerrilla/log"
"github.com/jpillora/ipfilter"
log "github.com/phires/go-guerrilla/log"
)
const (
DefaultSTMPPort = 465
DefaultSMTPPort = 465
DefaultMaxEmailSize = (10 << 23) // 83 MB
DefaultLocalListenIP = "0.0.0.0"
DefaultLocalListenPort = 2525
@ -95,10 +95,6 @@ func run() error {
file.Close()
for _, eachline := range allowedIPsAndRanges {
fmt.Println(eachline)
}
AllowedSendersFilter = ipfilter.New(ipfilter.Options{
//AllowedIPs: []string{"192.168.0.0/24"},
AllowedIPs: allowedIPsAndRanges,
@ -106,12 +102,6 @@ func run() error {
})
}
err = Start(appConfig, verbose)
if err != nil {
flag.Usage()
return fmt.Errorf("starting server: %w", err)
}
logLevel := "info"
if verbose {
logLevel = "debug"
@ -121,6 +111,12 @@ func run() error {
return fmt.Errorf("creating logger: %w", err)
}
err = Start(appConfig, verbose)
if err != nil {
flag.Usage()
return fmt.Errorf("starting server: %w", err)
}
if test {
err = sendTest(testsender, testrcpt, appConfig.LocalListenPort)
if err != nil {
@ -164,11 +160,16 @@ func loadConfig(path string) (*mailRelayConfig, error) {
if err := parser.Decode(&cfg); err != nil {
return nil, err
}
if err := validateConfig(&cfg); err != nil {
return nil, fmt.Errorf("invalid configuration: %w", err)
}
return &cfg, nil
}
func configDefaults(config *mailRelayConfig) {
config.SMTPPort = DefaultSTMPPort
config.SMTPPort = DefaultSMTPPort
config.SMTPStartTLS = false
config.SMTPLoginAuthType = false
config.MaxEmailSize = DefaultMaxEmailSize
@ -180,6 +181,31 @@ func configDefaults(config *mailRelayConfig) {
config.TimeoutSecs = DefaultTimeoutSecs
}
// validateConfig validates the configuration values
func validateConfig(config *mailRelayConfig) error {
if config.SMTPServer == "" {
return errors.New("smtp_server is required")
}
if config.SMTPPort < 1 || config.SMTPPort > 65535 {
return errors.New("smtp_port must be between 1 and 65535")
}
if config.LocalListenPort < 1 || config.LocalListenPort > 65535 {
return errors.New("local_listen_port must be between 1 and 65535")
}
if config.MaxEmailSize < 1024 {
return errors.New("smtp_max_email_size must be at least 1024 bytes")
}
if config.TimeoutSecs < 1 || config.TimeoutSecs > 3600 {
return errors.New("timeout_secs must be between 1 and 3600 seconds")
}
return nil
}
// sendTest sends a test message to the SMTP server specified in mailrelay.json
func sendTest(sender string, rcpt string, port int) error {
conn, err := smtp.Dial(fmt.Sprintf("localhost:%d", port))

View File

@ -18,24 +18,24 @@ import (
// MockSMTPServer represents a mock SMTP server for testing
type MockSMTPServer struct {
listener net.Listener
tlsConfig *tls.Config
address string
port int
running bool
mu sync.Mutex
listener net.Listener
tlsConfig *tls.Config
address string
port int
running bool
mu sync.Mutex
// Recorded interactions
Connections []MockConnection
// Configuration
RequireAuth bool
RequireSTARTTLS bool
SupportLoginAuth bool
ResponseDelay time.Duration
FailCommands map[string]bool // Commands to fail
CustomResponses map[string]string
ImplicitTLS bool // True if server uses implicit TLS (like port 465)
RequireAuth bool
RequireSTARTTLS bool
SupportLoginAuth bool
ResponseDelay time.Duration
FailCommands map[string]bool // Commands to fail
CustomResponses map[string]string
ImplicitTLS bool // True if server uses implicit TLS (like port 465)
}
type MockConnection struct {
@ -295,7 +295,6 @@ func (s *MockSMTPServer) handleSTARTTLS(conn net.Conn, reader *bufio.Reader, wri
return tlsConn, newReader, newWriter, true
}
func (s *MockSMTPServer) handleAUTH(parts []string, reader *bufio.Reader, writer *bufio.Writer, mockConn *MockConnection) {
if len(parts) < 2 {
writer.WriteString("501 Syntax error\r\n")
@ -426,12 +425,12 @@ func generateTestCert() (tls.Certificate, error) {
StreetAddress: []string{""},
PostalCode: []string{""},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(365 * 24 * time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback},
DNSNames: []string{"localhost"},
NotBefore: time.Now(),
NotAfter: time.Now().Add(365 * 24 * time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback},
DNSNames: []string{"localhost"},
}
// Generate the certificate

View File

@ -3,10 +3,10 @@ package main
import (
"fmt"
guerrilla "github.com/flashmob/go-guerrilla"
"github.com/flashmob/go-guerrilla/backends"
"github.com/flashmob/go-guerrilla/log"
"github.com/flashmob/go-guerrilla/mail"
guerrilla "github.com/phires/go-guerrilla"
"github.com/phires/go-guerrilla/backends"
"github.com/phires/go-guerrilla/log"
"github.com/phires/go-guerrilla/mail"
)
const (
@ -39,7 +39,6 @@ func Start(appConfig *mailRelayConfig, verbose bool) (err error) {
"save_workers_size": saveWorkersSize,
"save_process": "HeadersParser|Header|Hasher|Debugger|MailRelay",
"log_received_mails": true,
"primary_mail_host": "homeoffice.com",
"smtp_username": appConfig.SMTPUsername,
"smtp_password": appConfig.SMTPPassword,
"smtp_server": appConfig.SMTPServer,

View File

@ -4,8 +4,8 @@ import (
"bytes"
"testing"
"github.com/flashmob/go-guerrilla/mail"
"github.com/jpillora/ipfilter"
"github.com/phires/go-guerrilla/mail"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)