diff --git a/auth_test.go b/auth_test.go index 029879c..84f4a50 100644 --- a/auth_test.go +++ b/auth_test.go @@ -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", @@ -101,4 +101,4 @@ func TestLoginAuthNext(t *testing.T) { } }) } -} \ No newline at end of file +} diff --git a/client.go b/client.go index 1d5afe7..d8dac75 100644 --- a/client.go +++ b/client.go @@ -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, } diff --git a/client_test.go b/client_test.go index 158876d..fefbcc7 100644 --- a/client_test.go +++ b/client_test.go @@ -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" ) @@ -34,7 +34,7 @@ func TestGetTo(t *testing.T) { }, expected: []string{ "user1@example.com", - "user2@test.com", + "user2@test.com", "admin@company.org", }, }, @@ -102,4 +102,4 @@ func TestIsQuitError(t *testing.T) { assert.Equal(t, tt.expected, result) }) } -} \ No newline at end of file +} diff --git a/config_test.go b/config_test.go index d6d4750..0900819 100644 --- a/config_test.go +++ b/config_test.go @@ -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) @@ -94,4 +94,4 @@ func TestLoadConfig(t *testing.T) { } }) } -} \ No newline at end of file +} diff --git a/go.mod b/go.mod index 10ca08e..0a6b969 100644 --- a/go.mod +++ b/go.mod @@ -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 ) diff --git a/go.sum b/go.sum index 464dfbb..ddbdccd 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/integration_test.go b/integration_test.go index e42e21c..03d4463 100644 --- a/integration_test.go +++ b/integration_test.go @@ -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", @@ -367,4 +367,4 @@ func TestSendMail_ConnectionTimeout(t *testing.T) { conn := server.GetLastConnection() require.NotNil(t, conn) assert.Equal(t, "sender@test.com", conn.From) -} \ No newline at end of file +} diff --git a/main.go b/main.go index 2fd64fa..e588865 100644 --- a/main.go +++ b/main.go @@ -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)) diff --git a/mock_smtp_server.go b/mock_smtp_server.go index 73efdd2..35e3db8 100644 --- a/mock_smtp_server.go +++ b/mock_smtp_server.go @@ -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 { @@ -84,7 +84,7 @@ func (s *MockSMTPServer) Start() error { s.running = true go s.acceptConnections() - + // Give the server a moment to start time.Sleep(10 * time.Millisecond) return nil @@ -108,7 +108,7 @@ func (s *MockSMTPServer) StartTLS() error { s.ImplicitTLS = true go s.acceptConnections() - + // Give the server a moment to start time.Sleep(10 * time.Millisecond) return nil @@ -139,7 +139,7 @@ func (s *MockSMTPServer) Port() int { func (s *MockSMTPServer) GetLastConnection() *MockConnection { s.mu.Lock() defer s.mu.Unlock() - + if len(s.Connections) == 0 { return nil } @@ -150,7 +150,7 @@ func (s *MockSMTPServer) GetLastConnection() *MockConnection { func (s *MockSMTPServer) Reset() { s.mu.Lock() defer s.mu.Unlock() - + s.Connections = make([]MockConnection, 0) } @@ -163,21 +163,21 @@ func (s *MockSMTPServer) acceptConnections() { } continue } - + go s.handleConnection(conn) } } func (s *MockSMTPServer) handleConnection(conn net.Conn) { defer conn.Close() - + if s.ResponseDelay > 0 { time.Sleep(s.ResponseDelay) } reader := bufio.NewReader(conn) writer := bufio.NewWriter(conn) - + mockConn := MockConnection{ Commands: make([]string, 0), To: make([]string, 0), @@ -200,21 +200,21 @@ func (s *MockSMTPServer) handleConnection(conn net.Conn) { line = strings.TrimSpace(line) mockConn.Commands = append(mockConn.Commands, line) - + parts := strings.Fields(line) if len(parts) == 0 { continue } - + cmd := strings.ToUpper(parts[0]) - + // Check if we should fail this command if s.FailCommands[cmd] { writer.WriteString("550 Command failed\r\n") writer.Flush() continue } - + // Check for custom responses if response, exists := s.CustomResponses[cmd]; exists { writer.WriteString(response + "\r\n") @@ -253,7 +253,7 @@ func (s *MockSMTPServer) handleConnection(conn net.Conn) { writer.Flush() } } - + s.mu.Lock() s.Connections = append(s.Connections, mockConn) s.mu.Unlock() @@ -278,24 +278,23 @@ func (s *MockSMTPServer) handleEHLO(writer *bufio.Writer) { func (s *MockSMTPServer) handleSTARTTLS(conn net.Conn, reader *bufio.Reader, writer *bufio.Writer, mockConn *MockConnection) (*tls.Conn, *bufio.Reader, *bufio.Writer, bool) { writer.WriteString("220 Ready to start TLS\r\n") writer.Flush() - + // Upgrade the connection to TLS tlsConn := tls.Server(conn, s.tlsConfig) if err := tlsConn.Handshake(); err != nil { // TLS handshake failed, return original connection return nil, reader, writer, false } - + mockConn.UsedTLS = true - + // Return new TLS connection and readers/writers newReader := bufio.NewReader(tlsConn) newWriter := bufio.NewWriter(tlsConn) - + 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") @@ -304,7 +303,7 @@ func (s *MockSMTPServer) handleAUTH(parts []string, reader *bufio.Reader, writer } authType := strings.ToUpper(parts[1]) - + switch authType { case "PLAIN": // PLAIN auth can be sent in initial command or as a response to challenge @@ -313,40 +312,40 @@ func (s *MockSMTPServer) handleAUTH(parts []string, reader *bufio.Reader, writer // authData := parts[2] // In a real implementation, we'd decode base64 and parse username/password mockConn.AuthUser = "testuser" mockConn.AuthPass = "testpass" - + writer.WriteString("235 Authentication successful\r\n") writer.Flush() } else { // Challenge/response mode writer.WriteString("334 \r\n") writer.Flush() - + authData, _ := reader.ReadString('\n') authData = strings.TrimSpace(authData) // In a real implementation, we'd decode base64 and parse username/password mockConn.AuthUser = "testuser" mockConn.AuthPass = "testpass" - + writer.WriteString("235 Authentication successful\r\n") writer.Flush() } - + case "LOGIN": writer.WriteString("334 VXNlcm5hbWU6\r\n") // "Username:" in base64 writer.Flush() - + username, _ := reader.ReadString('\n') mockConn.AuthUser = strings.TrimSpace(username) - + writer.WriteString("334 UGFzc3dvcmQ6\r\n") // "Password:" in base64 writer.Flush() - + password, _ := reader.ReadString('\n') mockConn.AuthPass = strings.TrimSpace(password) - + writer.WriteString("235 Authentication successful\r\n") writer.Flush() - + default: writer.WriteString("504 Authentication mechanism not supported\r\n") writer.Flush() @@ -359,11 +358,11 @@ func (s *MockSMTPServer) handleMAIL(parts []string, writer *bufio.Writer, mockCo writer.Flush() return } - + fromAddr := strings.TrimPrefix(parts[1], "FROM:") fromAddr = strings.Trim(fromAddr, "<>") mockConn.From = fromAddr - + writer.WriteString("250 OK\r\n") writer.Flush() } @@ -374,11 +373,11 @@ func (s *MockSMTPServer) handleRCPT(parts []string, writer *bufio.Writer, mockCo writer.Flush() return } - + toAddr := strings.TrimPrefix(parts[1], "TO:") toAddr = strings.Trim(toAddr, "<>") mockConn.To = append(mockConn.To, toAddr) - + writer.WriteString("250 OK\r\n") writer.Flush() } @@ -386,23 +385,23 @@ func (s *MockSMTPServer) handleRCPT(parts []string, writer *bufio.Writer, mockCo func (s *MockSMTPServer) handleDATA(reader *bufio.Reader, writer *bufio.Writer, mockConn *MockConnection) { writer.WriteString("354 Start mail input; end with .\r\n") writer.Flush() - + var dataBuilder strings.Builder for { line, err := reader.ReadString('\n') if err != nil { break } - + if strings.TrimSpace(line) == "." { break } - + dataBuilder.WriteString(line) } - + mockConn.Data = dataBuilder.String() - + writer.WriteString("250 OK: message accepted\r\n") writer.Flush() } @@ -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 @@ -445,4 +444,4 @@ func generateTestCert() (tls.Certificate, error) { Certificate: [][]byte{certDER}, PrivateKey: priv, }, nil -} \ No newline at end of file +} diff --git a/server.go b/server.go index 891156e..b03a7cc 100644 --- a/server.go +++ b/server.go @@ -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, diff --git a/tls_test.go b/tls_test.go index ad13802..13c56c9 100644 --- a/tls_test.go +++ b/tls_test.go @@ -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" ) @@ -233,11 +233,11 @@ func TestSendMail_TLSSkipVerify(t *testing.T) { // Send email err := sendMail(envelope, config) - + if tt.skipVerify { // Should succeed when skipping verification assert.NoError(t, err) - + // Verify email was sent conn := server.GetLastConnection() require.NotNil(t, conn) @@ -249,4 +249,4 @@ func TestSendMail_TLSSkipVerify(t *testing.T) { } }) } -} \ No newline at end of file +}