Compare commits

...

3 commits
v1.1.0 ... main

2 changed files with 11 additions and 28 deletions

View file

@ -22,10 +22,9 @@ var DatabaseBackend = smtp.DatabaseBackend{
// AuthenticationBackend is a smtp.AuthenticationBackend implementation that always returns a fixed address for Authenticate. // AuthenticationBackend is a smtp.AuthenticationBackend implementation that always returns a fixed address for Authenticate.
var AuthenticationBackend = smtp.AuthenticationBackend{ var AuthenticationBackend = smtp.AuthenticationBackend{
Authenticate: func(initial string, conn *textproto.Conn) (*smtp.Address, error) { Authenticate: func(initial string, conn *textproto.Conn) (smtp.CheckAddress, error) {
return &smtp.Address{ return func(address *smtp.Address) (bool, error) {
Name: "test", return true, nil
Address: "example.org",
}, nil }, nil
}, },
} }

32
smtp.go
View file

@ -58,7 +58,8 @@ type DatabaseBackend struct {
// AuthenticationBackend is a struct that represents an authentication backend // AuthenticationBackend is a struct that represents an authentication backend
type AuthenticationBackend struct { type AuthenticationBackend struct {
Authenticate func(initial string, conn *textproto.Conn) (CheckAddress, error) Authenticate func(initial string, conn *textproto.Conn) (CheckAddress, error)
SupportedMechanisms []string
} }
type CheckAddress func(*Address) (bool, error) type CheckAddress func(*Address) (bool, error)
@ -211,8 +212,6 @@ func (fr *Receiver) handleConnection(conn net.Conn) {
return return
} }
fmt.Println("Connection from", conn.RemoteAddr().String())
for { for {
line, err := textProto.ReadLine() line, err := textProto.ReadLine()
if err != nil { if err != nil {
@ -283,6 +282,9 @@ func (fr *Receiver) handleConnection(conn net.Conn) {
if fr.enforceTLS { if fr.enforceTLS {
capabilities = append(capabilities, "250-REQUIRETLS") capabilities = append(capabilities, "250-REQUIRETLS")
} }
if fr.auth.SupportedMechanisms != nil {
capabilities = append(capabilities, "250-AUTH "+strings.Join(fr.auth.SupportedMechanisms, " "))
}
capabilities = append(capabilities, defaultCapabilities...) capabilities = append(capabilities, defaultCapabilities...)
state.HELO = true state.HELO = true
err = speakMultiLine(textProto, capabilities) err = speakMultiLine(textProto, capabilities)
@ -324,7 +326,7 @@ func (fr *Receiver) handleConnection(conn net.Conn) {
} else { } else {
checkAddress, err := fr.auth.Authenticate(strings.TrimPrefix(line, "AUTH "), textProto) checkAddress, err := fr.auth.Authenticate(strings.TrimPrefix(line, "AUTH "), textProto)
if err != nil { if err != nil {
_ = textProto.PrintfLine("421 4.7.0 Temporary server error") _ = textProto.PrintfLine(err.Error())
_ = conn.Close() _ = conn.Close()
return return
} }
@ -588,7 +590,6 @@ func (fr *Receiver) handleConnection(conn net.Conn) {
Host: strings.Split(conn.RemoteAddr().String(), ":")[0], Host: strings.Split(conn.RemoteAddr().String(), ":")[0],
} }
go sendEmail(SenderArgs{ go sendEmail(SenderArgs{
Hostname: fr.hostname,
EnforceTLS: fr.enforceTLS, EnforceTLS: fr.enforceTLS,
}, mail, fr.database, queueID) }, mail, fr.database, queueID)
@ -617,7 +618,6 @@ func (fr *Receiver) handleConnection(conn net.Conn) {
// SenderArgs is a struct that represents the arguments for the Sender // SenderArgs is a struct that represents the arguments for the Sender
type SenderArgs struct { type SenderArgs struct {
Hostname string
EnforceTLS bool EnforceTLS bool
} }
@ -648,7 +648,7 @@ func Send(args SenderArgs, mail *Mail, conn net.Conn, mxHost string) (err error)
return errors.New("unexpected greeting - " + line) return errors.New("unexpected greeting - " + line)
} }
err = textConn.PrintfLine("EHLO %s", args.Hostname) err = textConn.PrintfLine("EHLO %s", mxHost)
if err != nil { if err != nil {
return err return err
} }
@ -682,16 +682,11 @@ func Send(args SenderArgs, mail *Mail, conn net.Conn, mxHost string) (err error)
InsecureSkipVerify: false, InsecureSkipVerify: false,
}) })
err = tlsConn.Handshake()
if err != nil {
return err
}
textConn = textproto.NewConn(tlsConn) textConn = textproto.NewConn(tlsConn)
// Just use HELO, no point using EHLO when we already have all the capabilities // Just use HELO, no point using EHLO when we already have all the capabilities
// This also gets us out of using readMultilineCodeResponse // This also gets us out of using readMultilineCodeResponse
err = textConn.PrintfLine("HELO %s", args.Hostname) err = textConn.PrintfLine("HELO %s", mxHost)
if err != nil { if err != nil {
return err return err
} }
@ -714,10 +709,7 @@ func Send(args SenderArgs, mail *Mail, conn net.Conn, mxHost string) (err error)
} }
code, line, err = textConn.ReadCodeLine(0) code, line, err = textConn.ReadCodeLine(0)
fmt.Println(code, line, err)
if err != nil { if err != nil {
// For some reason the EHLO stuff ends up here
fmt.Println("5")
return err return err
} }
@ -732,9 +724,7 @@ func Send(args SenderArgs, mail *Mail, conn net.Conn, mxHost string) (err error)
} }
code, line, err = textConn.ReadCodeLine(0) code, line, err = textConn.ReadCodeLine(0)
fmt.Println(code, line, err)
if err != nil { if err != nil {
fmt.Println("6")
return err return err
} }
@ -749,9 +739,7 @@ func Send(args SenderArgs, mail *Mail, conn net.Conn, mxHost string) (err error)
} }
code, line, err = textConn.ReadCodeLine(0) code, line, err = textConn.ReadCodeLine(0)
fmt.Println(code, line, err)
if err != nil { if err != nil {
fmt.Println("7")
return err return err
} }
@ -771,9 +759,7 @@ func Send(args SenderArgs, mail *Mail, conn net.Conn, mxHost string) (err error)
} }
code, line, err = textConn.ReadCodeLine(0) code, line, err = textConn.ReadCodeLine(0)
fmt.Println(code, line, err)
if err != nil { if err != nil {
fmt.Println("8")
return err return err
} }
@ -787,9 +773,7 @@ func Send(args SenderArgs, mail *Mail, conn net.Conn, mxHost string) (err error)
} }
code, line, err = textConn.ReadCodeLine(0) code, line, err = textConn.ReadCodeLine(0)
fmt.Println(code, line, err)
if err != nil { if err != nil {
fmt.Println("9")
return err return err
} }