diff --git a/backend.go b/backend.go index 93d8199..dd7b938 100644 --- a/backend.go +++ b/backend.go @@ -14,11 +14,11 @@ var ( type Backend interface { // Authenticate a user. Return smtp.ErrAuthUnsupported if you don't want to // support this. - Login(username, password string) (User, error) + Login(state *ConnectionState, username, password string) (User, error) // Called if the client attempts to send mail without logging in first. // Return smtp.ErrAuthRequired if you don't want to support this. - AnonymousLogin() (User, error) + AnonymousLogin(state *ConnectionState) (User, error) } // An authenticated user. diff --git a/backendutil/transform.go b/backendutil/transform.go index f253029..4a9a422 100644 --- a/backendutil/transform.go +++ b/backendutil/transform.go @@ -8,21 +8,21 @@ import ( // TransformBackend is a backend that transforms messages. type TransformBackend struct { - Backend smtp.Backend + Backend smtp.Backend Transform func(from string, to []string, r io.Reader) (string, []string, io.Reader, error) } // Login implements the smtp.Backend interface. -func (be *TransformBackend) Login(username, password string) (smtp.User, error) { - u, err := be.Backend.Login(username, password) +func (be *TransformBackend) Login(state *smtp.ConnectionState, username, password string) (smtp.User, error) { + u, err := be.Backend.Login(state, username, password) if err != nil { return nil, err } return &transformUser{u, be}, nil } -func (be *TransformBackend) AnonymousLogin() (smtp.User, error) { - u, err := be.Backend.AnonymousLogin() +func (be *TransformBackend) AnonymousLogin(state *smtp.ConnectionState) (smtp.User, error) { + u, err := be.Backend.AnonymousLogin(state) if err != nil { return nil, err } diff --git a/conn.go b/conn.go index a4e9060..f29325b 100644 --- a/conn.go +++ b/conn.go @@ -25,6 +25,12 @@ type message struct { To []string } +type ConnectionState struct { + Hostname string + RemoteAddr net.Addr + TLS tls.ConnectionState +} + type Conn struct { conn net.Conn text *textproto.Conn @@ -160,6 +166,19 @@ func (c *Conn) TLSConnectionState() (state tls.ConnectionState, ok bool) { return tc.ConnectionState(), true } +func (c *Conn) State() ConnectionState { + state := ConnectionState{} + tlsState, ok := c.TLSConnectionState() + if ok { + state.TLS = tlsState + } + + state.Hostname = c.helo + state.RemoteAddr = c.conn.RemoteAddr() + + return state +} + func (c *Conn) authAllowed() bool { _, isTLS := c.TLSConnectionState() return !c.server.AuthDisabled && (isTLS || c.server.AllowInsecureAuth) @@ -216,7 +235,8 @@ func (c *Conn) handleMail(arg string) { } if c.User() == nil { - user, err := c.server.Backend.AnonymousLogin() + state := c.State() + user, err := c.server.Backend.AnonymousLogin(&state) if err != nil { c.WriteResponse(502, err.Error()) return diff --git a/server.go b/server.go index 0ef64fd..4347248 100755 --- a/server.go +++ b/server.go @@ -60,7 +60,8 @@ func NewServer(be Backend) *Server { return errors.New("Identities not supported") } - user, err := be.Login(username, password) + state := conn.State() + user, err := be.Login(&state, username, password) if err != nil { return err } diff --git a/server_test.go b/server_test.go index 0fb9039..2b20e12 100644 --- a/server_test.go +++ b/server_test.go @@ -25,7 +25,7 @@ type backend struct { userErr error } -func (be *backend) Login(username, password string) (smtp.User, error) { +func (be *backend) Login(_ *smtp.ConnectionState, username, password string) (smtp.User, error) { if be.userErr != nil { return &user{}, be.userErr } @@ -36,7 +36,7 @@ func (be *backend) Login(username, password string) (smtp.User, error) { return &user{backend: be}, nil } -func (be *backend) AnonymousLogin() (smtp.User, error) { +func (be *backend) AnonymousLogin(_ *smtp.ConnectionState) (smtp.User, error) { if be.userErr != nil { return &user{}, be.userErr }