]>
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(250, 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
)
78 conn
.writeReply(550, "access denied")
82 conn
.writeReply(250, "https://tools.ietf.org/html/rfc5321")
84 conn
.writeReply(500, "unrecognized command")
91 func (conn
*connection
) reply(reply ReplyLine
) {
92 conn
.writeReply(reply
.Code
, reply
.Message
)
95 func (conn
*connection
) writeReply(code
int, msg
string) {
97 conn
.tp
.PrintfLine("%d %s", code
, msg
)
99 conn
.tp
.PrintfLine("%d", code
)
103 func (conn
*connection
) doEHLO() {
107 _
, err
:= fmt
.Sscanf(conn
.line
, "%s %s", &cmd
, &conn
.ehlo
)
109 conn
.reply(ReplyBadSyntax
)
114 conn
.writeReply(250, fmt
.Sprintf("Hello %s [%s]", conn
.ehlo
, conn
.remoteAddr
))
116 conn
.tp
.PrintfLine("250-Hello %s [%s]", conn
.ehlo
, conn
.remoteAddr
)
117 if conn
.server
.TLSConfig() != nil {
118 conn
.tp
.PrintfLine("250-STARTTLS")
120 conn
.tp
.PrintfLine("250 SIZE %d", 40960000)
123 conn
.state
= stateInitial
126 func (conn
*connection
) doMAIL() {
127 if conn
.state
!= stateInitial
{
128 conn
.reply(ReplyBadSequence
)
133 _
, err
:= fmt
.Sscanf(conn
.line
, "MAIL FROM:%s", &mailFrom
)
135 conn
.reply(ReplyBadSyntax
)
139 conn
.mailFrom
, err
= mail
.ParseAddress(mailFrom
)
141 conn
.reply(ReplyBadSyntax
)
145 conn
.state
= stateMail
149 func (conn
*connection
) doRCPT() {
150 if conn
.state
!= stateMail
&& conn
.state
!= stateRecipient
{
151 conn
.reply(ReplyBadSequence
)
156 _
, err
:= fmt
.Sscanf(conn
.line
, "RCPT TO:%s", &rcptTo
)
158 conn
.reply(ReplyBadSyntax
)
162 address
, err
:= mail
.ParseAddress(rcptTo
)
164 conn
.reply(ReplyBadSyntax
)
167 conn
.rcptTo
= append(conn
.rcptTo
, *address
)
169 conn
.state
= stateRecipient
173 func (conn
*connection
) doDATA() {
174 if conn
.state
!= stateRecipient
{
175 conn
.reply(ReplyBadSequence
)
179 conn
.writeReply(354, "Start mail input; end with <CRLF>.<CRLF>")
181 data
, err
:= conn
.tp
.ReadDotBytes()
184 conn
.writeReply(552, "transaction failed")
189 RemoteAddr
: conn
.remoteAddr
,
191 MailFrom
: *conn
.mailFrom
,
196 if reply
:= conn
.server
.OnMessageDelivered(env
); reply
!= nil {
201 conn
.state
= stateInitial
205 func (conn
*connection
) doVRFY() {
208 func (conn
*connection
) doRSET() {
209 conn
.state
= stateInitial
214 func (conn
*connection
) resetBuffers() {
216 conn
.rcptTo
= make([]mail
.Address
, 0)