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