]>
src.bluestatic.org Git - mailpopbox.git/blob - smtp.go
11 "github.com/uber-go/zap"
13 "src.bluestatic.org/mailpopbox/smtp"
16 func runSMTPServer(config Config
, log zap
.Logger
) <-chan ServerControlMessage
{
19 controlChan
: make(chan ServerControlMessage
),
20 log
: log
.With(zap
.String("server", "smtp")),
23 return server
.controlChan
26 type smtpServer
struct {
32 controlChan
chan ServerControlMessage
35 func (server
*smtpServer
) run() {
36 if !server
.loadTLSConfig() {
40 addr
:= fmt
.Sprintf(":%d", server
.config
.SMTPPort
)
41 server
.log
.Info("starting server", zap
.String("address", addr
))
43 l
, err
:= net
.Listen("tcp", addr
)
45 server
.log
.Error("listen", zap
.Error(err
))
46 server
.controlChan
<- ServerControlFatalError
50 connChan
:= make(chan net
.Conn
)
51 go RunAcceptLoop(l
, connChan
, server
.log
)
53 reloadChan
:= CreateReloadSignal()
58 if !server
.loadTLSConfig() {
61 case conn
, ok
:= <-connChan
:
63 go smtp
.AcceptConnection(conn
, server
, server
.log
)
71 func (server
*smtpServer
) loadTLSConfig() bool {
73 server
.tlsConfig
, err
= server
.config
.GetTLSConfig()
75 server
.log
.Error("failed to configure TLS", zap
.Error(err
))
76 server
.controlChan
<- ServerControlFatalError
79 server
.log
.Info("loaded TLS config")
83 func (server
*smtpServer
) Name() string {
84 return server
.config
.Hostname
87 func (server
*smtpServer
) TLSConfig() *tls
.Config
{
88 return server
.tlsConfig
91 func (server
*smtpServer
) VerifyAddress(addr mail
.Address
) smtp
.ReplyLine
{
92 if server
.maildropForAddress(addr
) == "" {
93 return smtp
.ReplyBadMailbox
98 func (server
*smtpServer
) Authenticate(authz
, authc
, passwd
string) bool {
99 authcAddr
, err
:= mail
.ParseAddress(authc
)
104 authzAddr
, err
:= mail
.ParseAddress(authz
)
105 if authz
!= "" && err
!= nil {
109 domain
:= smtp
.DomainForAddress(*authcAddr
)
110 for _
, s
:= range server
.config
.Servers
{
111 if domain
== s
.Domain
{
112 authOk
:= authc
== MailboxAccount
+s
.Domain
&& passwd
== s
.MailboxPassword
113 if authzAddr
!= nil {
114 authOk
= authOk
&& smtp
.DomainForAddress(*authzAddr
) == domain
122 func (server
*smtpServer
) OnMessageDelivered(en smtp
.Envelope
) *smtp
.ReplyLine
{
123 maildrop
:= server
.maildropForAddress(en
.RcptTo
[0])
126 return &smtp
.ReplyBadMailbox
129 f
, err
:= os
.Create(path
.Join(maildrop
, en
.ID
+".msg"))
132 return &smtp
.ReplyBadMailbox
135 smtp
.WriteEnvelopeForDelivery(f
, en
)
140 func (server
*smtpServer
) maildropForAddress(addr mail
.Address
) string {
141 domain
:= smtp
.DomainForAddress(addr
)
142 for _
, s
:= range server
.config
.Servers
{
143 if domain
== s
.Domain
{
144 return s
.MaildropPath