Skip to content

Commit

Permalink
Pass connection information to backend
Browse files Browse the repository at this point in the history
Closes #15.
  • Loading branch information
foxcpp authored and emersion committed Mar 18, 2019
1 parent 2babd40 commit 7006326
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 11 deletions.
4 changes: 2 additions & 2 deletions backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
10 changes: 5 additions & 5 deletions backendutil/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
22 changes: 21 additions & 1 deletion conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
4 changes: 2 additions & 2 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
}
Expand Down

0 comments on commit 7006326

Please sign in to comment.