Compare commits

..

8 commits

Author SHA1 Message Date
194daa594d
more refractoring, adding makefile for tests 2025-03-14 12:46:30 +01:00
71409bf7cd
slight refractoring 2025-03-14 12:13:06 +01:00
fb16a3fc81
moved from log.Logger to slog.Logger 2025-03-14 12:07:44 +01:00
33c7d9338e
re-added SSL3.0 to envelope 2025-03-13 15:07:09 +01:00
e4e75cf975
cleaned up deprecations and warnings 2025-03-13 14:40:39 +01:00
Christian Joergensen
006a4f9d6d
Cleanup actions. (#15) 2022-09-30 12:51:37 -04:00
Christian Joergensen
737dbc490e
Run tests daily. (#14) 2022-09-27 20:24:12 -04:00
Alex SZAKALY
166abaf187
chore: add leading underscore to examples directory (#13)
Unfortunately the dependency github.com/eaigner/dkim
is no longer available

As a temporary solution we need to put leading underscore
to let Go recursively ignore it

Signed-off-by: Alex Szakaly <alex.szakaly@gmail.com>
2021-11-22 00:56:59 +01:00
15 changed files with 289 additions and 247 deletions

View file

@ -1,15 +1,17 @@
name: Go
name: smtpd
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
schedule:
- cron: '12 0 * * *'
jobs:
build:
name: Build
name: Build and Test
runs-on: ubuntu-latest
steps:
@ -19,16 +21,11 @@ jobs:
go-version: ^1.13
id: go
- name: Check out code into the Go module directory
- name: Check out the code
uses: actions/checkout@v2
- name: Get dependencies
run: |
go get -v -t -d ./...
if [ -f Gopkg.toml ]; then
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
dep ensure
fi
run: go get -v -t -d ./...
- name: Build
run: go build -v .

8
Makefile Normal file
View file

@ -0,0 +1,8 @@
test:
go test .
dkim-proxy:
cd _examples && go get . && go build .
testsum:
gotestsum --format testname

View file

@ -0,0 +1,5 @@
# smtpd dkim-proxy
## Important Note
The dependency `github.com/eaigner/dkim` is no longer available thus the example can not be built.

View file

@ -0,0 +1,5 @@
module github.com/chrj/smtpd/_examples/dkim-proxy
go 1.14
require github.com/eaigner/dkim v0.0.0-20150301120808-6fe4a7ee9cfb

View file

@ -4,7 +4,6 @@ package main
import (
"bytes"
"flag"
"io/ioutil"
"log"
"net/smtp"
@ -60,7 +59,7 @@ func main() {
log.Fatalf("DKIM configuration error: %v", err)
}
privKey, err = ioutil.ReadFile(*privKeyFile)
privKey, err = io.ReadFile(*privKeyFile)
if err != nil {
log.Fatalf("Couldn't read private key: %v", err)
}

View file

@ -20,7 +20,7 @@ func (env *Envelope) AddReceivedLine(peer Peer) {
tlsDetails := ""
tlsVersions := map[uint16]string{
tls.VersionSSL30: "SSL3.0",
0x300: "SSL3.0",
tls.VersionTLS10: "TLS1.0",
tls.VersionTLS11: "TLS1.1",
tls.VersionTLS12: "TLS1.2",

22
error.go Normal file
View file

@ -0,0 +1,22 @@
package smtpd
import (
"errors"
"fmt"
)
// Error represents an Error reported in the SMTP session.
type Error struct {
Code int // The integer error code
Message string // The error message
}
// Error returns a string representation of the SMTP error
func (e Error) Error() string {
return fmt.Sprintf("%d %s", e.Code, e.Message)
}
// ErrServerClosed is returned by the Server's Serve and ListenAndServe,
// methods after a call to Shutdown.
var ErrServerClosed = errors.New("smtp: Server closed")

View file

@ -5,7 +5,7 @@ import (
"net/smtp"
"strings"
"github.com/chrj/smtpd"
"git.jmbit.de/jmb/smtpd"
)
func ExampleServer() {

6
go.mod
View file

@ -1,5 +1,3 @@
module github.com/chrj/smtpd
module git.jmbit.de/jmb/smtpd
go 1.14
require github.com/eaigner/dkim v0.0.0-20150301120808-6fe4a7ee9cfb
go 1.24

28
onceCloseListerner.go Normal file
View file

@ -0,0 +1,28 @@
package smtpd
import (
"net"
"sync"
"sync/atomic"
)
// onceCloseListener wraps a net.Listener, protecting it from
// multiple Close calls.
type onceCloseListener struct {
net.Listener
once sync.Once
closeErr error
}
func (oc *onceCloseListener) Close() error {
oc.once.Do(oc.close)
return oc.closeErr
}
func (oc *onceCloseListener) close() { oc.closeErr = oc.Listener.Close() }
type atomicBool int32
func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) }
func (b *atomicBool) setFalse() { atomic.StoreInt32((*int32)(b), 0) }

View file

@ -7,7 +7,6 @@ import (
"encoding/base64"
"fmt"
"io"
"io/ioutil"
"net"
"net/textproto"
"strconv"
@ -288,6 +287,7 @@ func (session *session) handleRCPT(cmd command) {
}
func (session *session) handleSTARTTLS(cmd command) {
_ = cmd
if session.tls {
session.reply(502, "Already running in TLS")
@ -334,6 +334,7 @@ func (session *session) handleSTARTTLS(cmd command) {
}
func (session *session) handleDATA(cmd command) {
_ = cmd
if session.envelope == nil || len(session.envelope.Recipients) == 0 {
session.reply(502, "Missing RCPT TO command.")
@ -371,7 +372,7 @@ func (session *session) handleDATA(cmd command) {
}
// Discard the rest and report an error.
_, err = io.Copy(ioutil.Discard, reader)
_, err = io.Copy(io.Discard, reader)
if err != nil {
// Network error, ignore
@ -390,17 +391,20 @@ func (session *session) handleDATA(cmd command) {
}
func (session *session) handleRSET(cmd command) {
_ = cmd
session.reset()
session.reply(250, "Go ahead")
return
}
func (session *session) handleNOOP(cmd command) {
_ = cmd
session.reply(250, "Go ahead")
return
}
func (session *session) handleQUIT(cmd command) {
_ = cmd
session.reply(221, "OK, bye")
session.close()
return

162
session.go Normal file
View file

@ -0,0 +1,162 @@
package smtpd
import (
"net"
"bufio"
"strings"
"fmt"
"time"
)
type session struct {
server *Server
peer Peer
envelope *Envelope
conn net.Conn
reader *bufio.Reader
writer *bufio.Writer
scanner *bufio.Scanner
tls bool
}
func (session *session) serve() {
defer session.close()
if !session.server.EnableProxyProtocol {
session.welcome()
}
for {
for session.scanner.Scan() {
line := session.scanner.Text()
session.logf("received: %s", strings.TrimSpace(line))
session.handle(line)
}
err := session.scanner.Err()
if err == bufio.ErrTooLong {
session.reply(500, "Line too long")
// Advance reader to the next newline
session.reader.ReadString('\n')
session.scanner = bufio.NewScanner(session.reader)
// Reset and have the client start over.
session.reset()
continue
}
break
}
}
func (session *session) reject() {
session.reply(421, "Too busy. Try again later.")
session.close()
}
func (session *session) reset() {
session.envelope = nil
}
func (session *session) welcome() {
if session.server.ConnectionChecker != nil {
err := session.server.ConnectionChecker(session.peer)
if err != nil {
session.error(err)
session.close()
return
}
}
session.reply(220, session.server.WelcomeMessage)
}
func (session *session) reply(code int, message string) {
session.logf("sending: %d %s", code, message)
fmt.Fprintf(session.writer, "%d %s\r\n", code, message)
session.flush()
}
func (session *session) flush() {
session.conn.SetWriteDeadline(time.Now().Add(session.server.WriteTimeout))
session.writer.Flush()
session.conn.SetReadDeadline(time.Now().Add(session.server.ReadTimeout))
}
func (session *session) error(err error) {
if smtpdError, ok := err.(Error); ok {
session.reply(smtpdError.Code, smtpdError.Message)
} else {
session.reply(502, fmt.Sprintf("%s", err))
}
}
func (session *session) logf(format string, v ...interface{}) {
if session.server.ProtocolLogger == nil {
return
}
session.server.ProtocolLogger.Info(fmt.Sprintf(
"%s [peer:%s]",
fmt.Sprintf(format, v...),
session.peer.Addr,
))
}
func (session *session) logError(err error, desc string) {
session.server.ProtocolLogger.Error(desc, "error", err)
}
func (session *session) extensions() []string {
extensions := []string{
fmt.Sprintf("SIZE %d", session.server.MaxMessageSize),
"8BITMIME",
"PIPELINING",
}
if session.server.EnableXCLIENT {
extensions = append(extensions, "XCLIENT")
}
if session.server.TLSConfig != nil && !session.tls {
extensions = append(extensions, "STARTTLS")
}
if session.server.Authenticator != nil && session.tls {
extensions = append(extensions, "AUTH PLAIN LOGIN")
}
return extensions
}
func (session *session) deliver() error {
if session.server.Handler != nil {
return session.server.Handler(session.peer, *session.envelope)
}
return nil
}
func (session *session) close() {
session.writer.Flush()
time.Sleep(200 * time.Millisecond)
session.conn.Close()
}

192
smtpd.go
View file

@ -6,11 +6,10 @@ import (
"crypto/tls"
"errors"
"fmt"
"log/slog"
"log"
"net"
"strings"
"sync"
"sync/atomic"
"time"
)
@ -51,7 +50,7 @@ type Server struct {
TLSConfig *tls.Config // Enable STARTTLS support.
ForceTLS bool // Force STARTTLS usage.
ProtocolLogger *log.Logger
ProtocolLogger *slog.Logger
// mu guards doneChan and makes closing it and listener atomic from
// perspective of Serve()
@ -84,34 +83,6 @@ type Peer struct {
TLS *tls.ConnectionState // TLS Connection details, if on TLS
}
// Error represents an Error reported in the SMTP session.
type Error struct {
Code int // The integer error code
Message string // The error message
}
// Error returns a string representation of the SMTP error
func (e Error) Error() string { return fmt.Sprintf("%d %s", e.Code, e.Message) }
// ErrServerClosed is returned by the Server's Serve and ListenAndServe,
// methods after a call to Shutdown.
var ErrServerClosed = errors.New("smtp: Server closed")
type session struct {
server *Server
peer Peer
envelope *Envelope
conn net.Conn
reader *bufio.Reader
writer *bufio.Writer
scanner *bufio.Scanner
tls bool
}
func (srv *Server) newSession(c net.Conn) (s *session) {
s = &session{
@ -190,7 +161,7 @@ func (srv *Server) Serve(l net.Listener) error {
default:
}
if ne, ok := e.(net.Error); ok && ne.Temporary() {
if ne, ok := e.(net.Error); ok && ne.Timeout() {
time.Sleep(time.Second)
continue
}
@ -297,143 +268,6 @@ func (srv *Server) configureDefaults() {
}
func (session *session) serve() {
defer session.close()
if !session.server.EnableProxyProtocol {
session.welcome()
}
for {
for session.scanner.Scan() {
line := session.scanner.Text()
session.logf("received: %s", strings.TrimSpace(line))
session.handle(line)
}
err := session.scanner.Err()
if err == bufio.ErrTooLong {
session.reply(500, "Line too long")
// Advance reader to the next newline
session.reader.ReadString('\n')
session.scanner = bufio.NewScanner(session.reader)
// Reset and have the client start over.
session.reset()
continue
}
break
}
}
func (session *session) reject() {
session.reply(421, "Too busy. Try again later.")
session.close()
}
func (session *session) reset() {
session.envelope = nil
}
func (session *session) welcome() {
if session.server.ConnectionChecker != nil {
err := session.server.ConnectionChecker(session.peer)
if err != nil {
session.error(err)
session.close()
return
}
}
session.reply(220, session.server.WelcomeMessage)
}
func (session *session) reply(code int, message string) {
session.logf("sending: %d %s", code, message)
fmt.Fprintf(session.writer, "%d %s\r\n", code, message)
session.flush()
}
func (session *session) flush() {
session.conn.SetWriteDeadline(time.Now().Add(session.server.WriteTimeout))
session.writer.Flush()
session.conn.SetReadDeadline(time.Now().Add(session.server.ReadTimeout))
}
func (session *session) error(err error) {
if smtpdError, ok := err.(Error); ok {
session.reply(smtpdError.Code, smtpdError.Message)
} else {
session.reply(502, fmt.Sprintf("%s", err))
}
}
func (session *session) logf(format string, v ...interface{}) {
if session.server.ProtocolLogger == nil {
return
}
session.server.ProtocolLogger.Output(2, fmt.Sprintf(
"%s [peer:%s]",
fmt.Sprintf(format, v...),
session.peer.Addr,
))
}
func (session *session) logError(err error, desc string) {
session.logf("%s: %v ", desc, err)
}
func (session *session) extensions() []string {
extensions := []string{
fmt.Sprintf("SIZE %d", session.server.MaxMessageSize),
"8BITMIME",
"PIPELINING",
}
if session.server.EnableXCLIENT {
extensions = append(extensions, "XCLIENT")
}
if session.server.TLSConfig != nil && !session.tls {
extensions = append(extensions, "STARTTLS")
}
if session.server.Authenticator != nil && session.tls {
extensions = append(extensions, "AUTH PLAIN LOGIN")
}
return extensions
}
func (session *session) deliver() error {
if session.server.Handler != nil {
return session.server.Handler(session.peer, *session.envelope)
}
return nil
}
func (session *session) close() {
session.writer.Flush()
time.Sleep(200 * time.Millisecond)
session.conn.Close()
}
// From net/http/server.go
func (s *Server) shuttingDown() bool {
@ -465,23 +299,3 @@ func (s *Server) closeDoneChanLocked() {
}
}
// onceCloseListener wraps a net.Listener, protecting it from
// multiple Close calls.
type onceCloseListener struct {
net.Listener
once sync.Once
closeErr error
}
func (oc *onceCloseListener) Close() error {
oc.once.Do(oc.close)
return oc.closeErr
}
func (oc *onceCloseListener) close() { oc.closeErr = oc.Listener.Close() }
type atomicBool int32
func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) }
func (b *atomicBool) setFalse() { atomic.StoreInt32((*int32)(b), 0) }

View file

@ -5,7 +5,7 @@ import (
"crypto/tls"
"errors"
"fmt"
"log"
"log/slog"
"net"
"net/smtp"
"net/textproto"
@ -14,7 +14,7 @@ import (
"testing"
"time"
"github.com/chrj/smtpd"
"git.jmbit.de/jmb/smtpd"
)
var localhostCert = []byte(`-----BEGIN CERTIFICATE-----
@ -158,7 +158,7 @@ func runsslserver(t *testing.T, server *smtpd.Server) (addr string, closer func(
func TestSMTP(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -233,7 +233,7 @@ func TestListenAndServe(t *testing.T) {
closer()
server := &smtpd.Server{
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
}
go func() {
@ -258,7 +258,7 @@ func TestSTARTTLS(t *testing.T) {
addr, closer := runsslserver(t, &smtpd.Server{
Authenticator: func(peer smtpd.Peer, username, password string) error { return nil },
ForceTLS: true,
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -347,7 +347,7 @@ func TestAuthRejection(t *testing.T) {
return smtpd.Error{Code: 550, Message: "Denied"}
},
ForceTLS: true,
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -371,7 +371,7 @@ func TestAuthNotSupported(t *testing.T) {
addr, closer := runsslserver(t, &smtpd.Server{
ForceTLS: true,
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -398,7 +398,7 @@ func TestAuthBypass(t *testing.T) {
return smtpd.Error{Code: 550, Message: "Denied"}
},
ForceTLS: true,
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -424,7 +424,7 @@ func TestConnectionCheck(t *testing.T) {
ConnectionChecker: func(peer smtpd.Peer) error {
return smtpd.Error{Code: 552, Message: "Denied"}
},
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -441,7 +441,7 @@ func TestConnectionCheckSimpleError(t *testing.T) {
ConnectionChecker: func(peer smtpd.Peer) error {
return errors.New("Denied")
},
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -461,7 +461,7 @@ func TestHELOCheck(t *testing.T) {
}
return smtpd.Error{Code: 552, Message: "Denied"}
},
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -483,7 +483,7 @@ func TestSenderCheck(t *testing.T) {
SenderChecker: func(peer smtpd.Peer, addr string) error {
return smtpd.Error{Code: 552, Message: "Denied"}
},
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -505,7 +505,7 @@ func TestRecipientCheck(t *testing.T) {
RecipientChecker: func(peer smtpd.Peer, addr string) error {
return smtpd.Error{Code: 552, Message: "Denied"}
},
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -529,7 +529,7 @@ func TestMaxMessageSize(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
MaxMessageSize: 5,
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -586,7 +586,7 @@ func TestHandler(t *testing.T) {
}
return nil
},
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -631,7 +631,7 @@ func TestRejectHandler(t *testing.T) {
Handler: func(peer smtpd.Peer, env smtpd.Envelope) error {
return smtpd.Error{Code: 550, Message: "Rejected"}
},
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -674,7 +674,7 @@ func TestMaxConnections(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
MaxConnections: 1,
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -696,7 +696,7 @@ func TestNoMaxConnections(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
MaxConnections: -1,
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -713,7 +713,7 @@ func TestMaxRecipients(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
MaxRecipients: 1,
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -744,7 +744,7 @@ func TestMaxRecipients(t *testing.T) {
func TestInvalidHelo(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -763,7 +763,7 @@ func TestInvalidHelo(t *testing.T) {
func TestInvalidSender(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -782,7 +782,7 @@ func TestInvalidSender(t *testing.T) {
func TestInvalidRecipient(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -805,7 +805,7 @@ func TestInvalidRecipient(t *testing.T) {
func TestRCPTbeforeMAIL(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -824,7 +824,7 @@ func TestRCPTbeforeMAIL(t *testing.T) {
func TestDATAbeforeRCPT(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -855,7 +855,7 @@ func TestInterruptedDATA(t *testing.T) {
t.Fatal("Accepted DATA despite disconnection")
return nil
},
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -893,7 +893,7 @@ func TestTimeoutClose(t *testing.T) {
MaxConnections: 1,
ReadTimeout: time.Second,
WriteTimeout: time.Second,
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -930,7 +930,7 @@ func TestTLSTimeout(t *testing.T) {
addr, closer := runsslserver(t, &smtpd.Server{
ReadTimeout: time.Second * 2,
WriteTimeout: time.Second * 2,
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -973,7 +973,7 @@ func TestTLSTimeout(t *testing.T) {
func TestLongLine(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -1012,7 +1012,7 @@ func TestXCLIENT(t *testing.T) {
}
return nil
},
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -1076,7 +1076,7 @@ func TestEnvelopeReceived(t *testing.T) {
return nil
},
ForceTLS: true,
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -1122,7 +1122,7 @@ func TestEnvelopeReceived(t *testing.T) {
func TestHELO(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -1158,7 +1158,7 @@ func TestLOGINAuth(t *testing.T) {
addr, closer := runsslserver(t, &smtpd.Server{
Authenticator: func(peer smtpd.Peer, username, password string) error { return nil },
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -1213,7 +1213,7 @@ func TestLOGINAuth(t *testing.T) {
func TestNullSender(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -1240,7 +1240,7 @@ func TestNullSender(t *testing.T) {
func TestNoBracketsSender(t *testing.T) {
addr, closer := runserver(t, &smtpd.Server{
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -1273,7 +1273,7 @@ func TestErrors(t *testing.T) {
server := &smtpd.Server{
Authenticator: func(peer smtpd.Peer, username, password string) error { return nil },
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
}
addr, closer := runserver(t, server)
@ -1356,7 +1356,7 @@ func TestMailformedMAILFROM(t *testing.T) {
}
return nil
},
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
})
defer closer()
@ -1402,7 +1402,7 @@ func TestTLSListener(t *testing.T) {
}
return nil
},
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
}
go func() {
@ -1440,7 +1440,7 @@ func TestTLSListener(t *testing.T) {
func TestShutdown(t *testing.T) {
fmt.Println("Starting test")
server := &smtpd.Server{
ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile),
ProtocolLogger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
}
ln, err := net.Listen("tcp", "127.0.0.1:0")