forked from emersion/go-smtp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackend.go
177 lines (150 loc) · 4.97 KB
/
backend.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package smtp
import (
"io"
)
var (
ErrAuthRequired = &SMTPError{
Code: 502,
EnhancedCode: EnhancedCode{5, 7, 0},
Message: "Please authenticate first",
}
ErrAuthUnsupported = &SMTPError{
Code: 502,
EnhancedCode: EnhancedCode{5, 7, 0},
Message: "Authentication not supported",
}
)
// A SMTP server backend.
type Backend interface {
NewSession(c *ConnectionState, hostname, sid string) (Session, error)
// Generate session unique id
GenerateSID() string
}
type BodyType string
const (
Body7Bit BodyType = "7BIT"
Body8BitMIME BodyType = "8BITMIME"
BodyBinaryMIME BodyType = "BINARYMIME"
)
type DSNReturn string
const (
// Attach the full copy of the message to any DSN that indicates
// a failure. Non-failure DSNs always contain the header only.
ReturnFull DSNReturn = "FULL"
// Attach only header of the message to any DSN that indicates a
// failure.
ReturnHeaders DSNReturn = "HDRS"
)
// MailOptions contains custom arguments that were
// passed as an argument to the MAIL command.
type MailOptions struct {
// Value of BODY= argument, 7BIT, 8BITMIME or BINARYMIME.
Body BodyType
// Size of the body. Can be 0 if not specified by client.
Size int
// TLS is required for the message transmission.
//
// The message should be rejected if it can't be transmitted
// with TLS.
RequireTLS bool
// The message envelope or message header contains UTF-8-encoded strings.
// This flag is set by SMTPUTF8-aware (RFC 6531) client.
UTF8 bool
// The authorization identity asserted by the message sender in decoded
// form with angle brackets stripped.
//
// nil value indicates missing AUTH, non-nil empty string indicates
// AUTH=<>.
//
// Defined in RFC 4954.
Auth *string
// Whether the full message or header only should be returned in
// failure DSNs.
//
// Defined in RFC 3461. Ignored if the server does not support DSN
// extension.
Return DSNReturn
// Envelope ID identifier. Returned in any DSN for the message.
//
// Not in xtext encoding. go-smtp restricts value to printable US-ASCII
// as required by specification.
//
// Defined in RFC 3461. Ignored if the server does not support DSN
// extension.
EnvelopeID string
}
type DSNNotify string
const (
NotifyNever DSNNotify = "NEVER"
NotifySuccess DSNNotify = "SUCCESS"
NotifyDelayed DSNNotify = "DELAYED"
NotifyFailure DSNNotify = "FAILURE"
)
type RcptOptions struct {
// When DSN should be generated for this recipient.
// As described in RFC 3461.
Notify []DSNNotify
// Original message recipient as described in RFC 3461.
//
// Value of OriginalRecipient is preserved as is. No xtext
// encoding/decoding or sanitization is done irregardless of
// OriginalRecipientType.
OriginalRecipient string
OriginalRecipientType string
}
// Session is used by servers to respond to an SMTP client.
//
// The methods are called when the remote client issues the matching command.
type Session interface {
// Discard currently processed message.
Reset()
// Free all resources associated with session.
Logout() error
// Authenticate the user using SASL PLAIN.
AuthPlain(username, password string) error
// Set return path for currently processed message.
Mail(from string, opts *MailOptions) error
// Add recipient for currently processed message.
Rcpt(to string, opts RcptOptions) error
// Set currently processed message contents and send it.
Data(r io.Reader) error
}
type ProxyBackend interface {
// AllowProxy method is called when client uses XCLIENT command without
// initialized session.
//
// Backends should implement this method AND returned Session objects
// should implement ProxySession for XCLIENT to work correctly.
AllowProxy(actual, asserted ConnectionState, sid string) bool
}
type ProxySession interface {
// AllowProxy method is called when client uses XCLIENT command.
//
// This is similar to ProxyBackend.AllowProxy but called instead of it if
// Session is already created for the user. Session.Logout will be
// called if this function returns true.
AllowProxy(asserted ConnectionState) bool
}
// LMTPSession is an add-on interface for Session. It can be implemented by
// LMTP servers to provide extra functionality.
type LMTPSession interface {
// LMTPData is the LMTP-specific version of Data method.
// It can be optionally implemented by the backend to provide
// per-recipient status information when it is used over LMTP
// protocol.
//
// LMTPData implementation sets status information using passed
// StatusCollector by calling SetStatus once per each AddRcpt
// call, even if AddRcpt was called multiple times with
// the same argument. SetStatus must not be called after
// LMTPData returns.
//
// Return value of LMTPData itself is used as a status for
// recipients that got no status set before using StatusCollector.
LMTPData(r io.Reader, status StatusCollector) error
}
// StatusCollector allows a backend to provide per-recipient status
// information.
type StatusCollector interface {
SetStatus(rcptTo string, err error)
}