]>
src.bluestatic.org Git - mailpopbox.git/blob - smtp/conn.go
13 stateNew state
= iota // Before EHLO.
20 type connection
struct {
30 mailFrom
*mail
.Address
34 func AcceptConnection(netConn net
.Conn
, server Server
) error
{
37 tp
: textproto
.NewConn(netConn
),
38 remoteAddr
: netConn
.RemoteAddr(),
44 conn
.writeReply(220, fmt
.Sprintf("%s ESMTP [%s] (mailpopbox)", server
.Name(), netConn
.LocalAddr()))
47 conn
.line
, err
= conn
.tp
.ReadLine()
49 conn
.writeReply(500, "line too long")
54 if _
, err
= fmt
.Sscanf(conn
.line
, "%s", &cmd
); err
!= nil {
55 conn
.reply(ReplyBadSyntax
)
61 conn
.writeReply(221, "Goodbye")
79 conn
.writeReply(550, "access denied")
83 conn
.writeReply(250, "https://tools.ietf.org/html/rfc5321")
85 conn
.writeReply(500, "unrecognized command")
92 func (conn
*connection
) reply(reply ReplyLine
) {
93 conn
.writeReply(reply
.Code
, reply
.Message
)
96 func (conn
*connection
) writeReply(code
int, msg
string) {
98 conn
.tp
.PrintfLine("%d %s", code
, msg
)
100 conn
.tp
.PrintfLine("%d", code
)
104 func (conn
*connection
) doEHLO() {
108 _
, err
:= fmt
.Sscanf(conn
.line
, "%s %s", &cmd
, &conn
.ehlo
)
110 conn
.reply(ReplyBadSyntax
)
115 conn
.writeReply(250, fmt
.Sprintf("Hello %s [%s]", conn
.ehlo
, conn
.remoteAddr
))
117 conn
.tp
.PrintfLine("250-Hello %s [%s]", conn
.ehlo
, conn
.remoteAddr
)
118 if conn
.server
.TLSConfig() != nil {
119 conn
.tp
.PrintfLine("250-STARTTLS")
121 conn
.tp
.PrintfLine("250 SIZE %d", 40960000)
124 conn
.state
= stateInitial
127 func (conn
*connection
) doMAIL() {
128 if conn
.state
!= stateInitial
{
129 conn
.reply(ReplyBadSequence
)
134 _
, err
:= fmt
.Sscanf(conn
.line
, "MAIL FROM:%s", &mailFrom
)
136 conn
.reply(ReplyBadSyntax
)
140 conn
.mailFrom
, err
= mail
.ParseAddress(mailFrom
)
142 conn
.reply(ReplyBadSyntax
)
146 conn
.state
= stateMail
150 func (conn
*connection
) doRCPT() {
151 if conn
.state
!= stateMail
&& conn
.state
!= stateRecipient
{
152 conn
.reply(ReplyBadSequence
)
157 _
, err
:= fmt
.Sscanf(conn
.line
, "RCPT TO:%s", &rcptTo
)
159 conn
.reply(ReplyBadSyntax
)
163 address
, err
:= mail
.ParseAddress(rcptTo
)
165 conn
.reply(ReplyBadSyntax
)
168 conn
.rcptTo
= append(conn
.rcptTo
, *address
)
170 conn
.state
= stateRecipient
174 func (conn
*connection
) doDATA() {
175 if conn
.state
!= stateRecipient
{
176 conn
.reply(ReplyBadSequence
)
180 conn
.writeReply(354, "Start mail input; end with <CRLF>.<CRLF>")
182 data
, err
:= conn
.tp
.ReadDotBytes()
185 conn
.writeReply(552, "transaction failed")
190 RemoteAddr
: conn
.remoteAddr
,
192 MailFrom
: *conn
.mailFrom
,
197 if reply
:= conn
.server
.OnMessageDelivered(env
); reply
!= nil {
202 conn
.state
= stateInitial
206 func (conn
*connection
) doVRFY() {
209 func (conn
*connection
) doRSET() {
210 conn
.state
= stateInitial
215 func (conn
*connection
) resetBuffers() {
217 conn
.rcptTo
= make([]mail
.Address
, 0)