backend.go raw

   1  package smtp
   2  
   3  import (
   4  	"io"
   5  
   6  	"github.com/emersion/go-sasl"
   7  )
   8  
   9  var (
  10  	ErrAuthFailed = &SMTPError{
  11  		Code:         535,
  12  		EnhancedCode: EnhancedCode{5, 7, 8},
  13  		Message:      "Authentication failed",
  14  	}
  15  	ErrAuthRequired = &SMTPError{
  16  		Code:         502,
  17  		EnhancedCode: EnhancedCode{5, 7, 0},
  18  		Message:      "Please authenticate first",
  19  	}
  20  	ErrAuthUnsupported = &SMTPError{
  21  		Code:         502,
  22  		EnhancedCode: EnhancedCode{5, 7, 0},
  23  		Message:      "Authentication not supported",
  24  	}
  25  	ErrAuthUnknownMechanism = &SMTPError{
  26  		Code:         504,
  27  		EnhancedCode: EnhancedCode{5, 7, 4},
  28  		Message:      "Unsupported authentication mechanism",
  29  	}
  30  )
  31  
  32  // A SMTP server backend.
  33  type Backend interface {
  34  	NewSession(c *Conn) (Session, error)
  35  }
  36  
  37  // BackendFunc is an adapter to allow the use of an ordinary function as a
  38  // Backend.
  39  type BackendFunc func(c *Conn) (Session, error)
  40  
  41  var _ Backend = (BackendFunc)(nil)
  42  
  43  // NewSession calls f(c).
  44  func (f BackendFunc) NewSession(c *Conn) (Session, error) {
  45  	return f(c)
  46  }
  47  
  48  // Session is used by servers to respond to an SMTP client.
  49  //
  50  // The methods are called when the remote client issues the matching command.
  51  type Session interface {
  52  	// Discard currently processed message.
  53  	Reset()
  54  
  55  	// Free all resources associated with session.
  56  	Logout() error
  57  
  58  	// Set return path for currently processed message.
  59  	Mail(from string, opts *MailOptions) error
  60  	// Add recipient for currently processed message.
  61  	Rcpt(to string, opts *RcptOptions) error
  62  	// Set currently processed message contents and send it.
  63  	//
  64  	// r must be consumed before Data returns.
  65  	Data(r io.Reader) error
  66  }
  67  
  68  // LMTPSession is an add-on interface for Session. It can be implemented by
  69  // LMTP servers to provide extra functionality.
  70  type LMTPSession interface {
  71  	Session
  72  
  73  	// LMTPData is the LMTP-specific version of Data method.
  74  	// It can be optionally implemented by the backend to provide
  75  	// per-recipient status information when it is used over LMTP
  76  	// protocol.
  77  	//
  78  	// LMTPData implementation sets status information using passed
  79  	// StatusCollector by calling SetStatus once per each AddRcpt
  80  	// call, even if AddRcpt was called multiple times with
  81  	// the same argument. SetStatus must not be called after
  82  	// LMTPData returns.
  83  	//
  84  	// Return value of LMTPData itself is used as a status for
  85  	// recipients that got no status set before using StatusCollector.
  86  	LMTPData(r io.Reader, status StatusCollector) error
  87  }
  88  
  89  // StatusCollector allows a backend to provide per-recipient status
  90  // information.
  91  type StatusCollector interface {
  92  	SetStatus(rcptTo string, err error)
  93  }
  94  
  95  // AuthSession is an add-on interface for Session. It provides support for the
  96  // AUTH extension.
  97  type AuthSession interface {
  98  	Session
  99  
 100  	AuthMechanisms() []string
 101  	Auth(mech string) (sasl.Server, error)
 102  }
 103