Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server: Move to using Backend.Features() instead of Enable* flags #112

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ type Backend interface {
AnonymousLogin(state *ConnectionState) (Session, error)
}

type Feature int32
emersion marked this conversation as resolved.
Show resolved Hide resolved

const (
FeatureNoSMTPUTF8 Feature = 2 << iota
emersion marked this conversation as resolved.
Show resolved Hide resolved
FeatureNoBINARYMIME
FeatureNoREQUIRETLS
)

type FeatureBackend interface {
emersion marked this conversation as resolved.
Show resolved Hide resolved
Features() Feature
}

type BodyType string

const (
Expand Down
13 changes: 7 additions & 6 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,13 +255,14 @@ func (c *Conn) handleGreet(enhanced bool, arg string) {

caps = append(caps, authCap)
}
if c.server.EnableSMTPUTF8 {
feat := c.server.backendFeatures()
if feat&FeatureNoSMTPUTF8 == 0 {
caps = append(caps, "SMTPUTF8")
}
if _, isTLS := c.TLSConnectionState(); isTLS && c.server.EnableREQUIRETLS {
if _, isTLS := c.TLSConnectionState(); isTLS && feat&FeatureNoREQUIRETLS == 0 {
caps = append(caps, "REQUIRETLS")
}
if c.server.EnableBINARYMIME {
if feat&FeatureNoBINARYMIME == 0 {
caps = append(caps, "BINARYMIME")
}
if c.server.MaxMessageBytes > 0 {
Expand Down Expand Up @@ -346,21 +347,21 @@ func (c *Conn) handleMail(arg string) {

opts.Size = int(size)
case "SMTPUTF8":
if !c.server.EnableSMTPUTF8 {
if c.server.backendFeatures()&FeatureNoSMTPUTF8 != 0 {
c.WriteResponse(504, EnhancedCode{5, 5, 4}, "SMTPUTF8 is not implemented")
return
}
opts.UTF8 = true
case "REQUIRETLS":
if !c.server.EnableREQUIRETLS {
if c.server.backendFeatures()&FeatureNoREQUIRETLS != 0 {
c.WriteResponse(504, EnhancedCode{5, 5, 4}, "REQUIRETLS is not implemented")
return
}
opts.RequireTLS = true
case "BODY":
switch value {
case "BINARYMIME":
if !c.server.EnableBINARYMIME {
if c.server.backendFeatures()&FeatureNoBINARYMIME != 0 {
c.WriteResponse(504, EnhancedCode{5, 5, 4}, "BINARYMIME is not implemented")
return
}
Expand Down
20 changes: 8 additions & 12 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,6 @@ type Server struct {
ReadTimeout time.Duration
WriteTimeout time.Duration

// Advertise SMTPUTF8 (RFC 6531) capability.
// Should be used only if backend supports it.
EnableSMTPUTF8 bool

// Advertise REQUIRETLS (RFC 8689) capability.
// Should be used only if backend supports it.
EnableREQUIRETLS bool

// Advertise BINARYMIME (RFC 3030) capability.
// Should be used only if backend supports it.
EnableBINARYMIME bool

// If set, the AUTH command will not be advertised and authentication
// attempts will be rejected. This setting overrides AllowInsecureAuth.
AuthDisabled bool
Expand Down Expand Up @@ -262,3 +250,11 @@ func (s *Server) ForEachConn(f func(*Conn)) {
f(conn)
}
}

func (s *Server) backendFeatures() Feature {
fb, ok := s.Backend.(FeatureBackend)
if !ok {
return 0
}
return fb.Features()
}
11 changes: 8 additions & 3 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,16 @@ type backend struct {
// Read N bytes of message before returning dataErr.
dataErrOffset int64

features smtp.Feature

panicOnMail bool
userErr error
}

func (be *backend) Features() smtp.Feature {
return be.features
}

func (be *backend) Login(_ *smtp.ConnectionState, username, password string) (smtp.Session, error) {
if be.userErr != nil {
return &session{}, be.userErr
Expand Down Expand Up @@ -339,7 +345,6 @@ func TestServerPanicRecover(t *testing.T) {

func TestServerSMTPUTF8(t *testing.T) {
_, s, c, scanner := testServerAuthenticated(t)
s.EnableSMTPUTF8 = true
defer s.Close()
defer c.Close()

Expand All @@ -353,9 +358,10 @@ func TestServerSMTPUTF8(t *testing.T) {
}

func TestServerSMTPUTF8_Disabled(t *testing.T) {
_, s, c, scanner := testServerAuthenticated(t)
be, s, c, scanner := testServerAuthenticated(t)
defer s.Close()
defer c.Close()
be.features = smtp.FeatureNoSMTPUTF8

io.WriteString(c, "MAIL FROM:<alice@wonderland.book> SMTPUTF8\r\n")
scanner.Scan()
Expand Down Expand Up @@ -1050,7 +1056,6 @@ func TestServer_Chunking_Binarymime(t *testing.T) {
be, s, c, scanner := testServerAuthenticated(t)
defer s.Close()
defer c.Close()
s.EnableBINARYMIME = true

io.WriteString(c, "MAIL FROM:<root@nsa.gov> BODY=BINARYMIME\r\n")
scanner.Scan()
Expand Down