]>
src.bluestatic.org Git - mailpopbox.git/blob - smtp.go
2 // Copyright 2020 Blue Static <https://www.bluestatic.org>
3 // This program is free software licensed under the GNU General Public License,
4 // version 3.0. The full text of the license can be found in LICENSE.txt.
5 // SPDX-License-Identifier: GPL-3.0-only
20 "src.bluestatic.org/mailpopbox/smtp"
23 func runSMTPServer(config Config
, log
*zap
.Logger
) <-chan ServerControlMessage
{
26 controlChan
: make(chan ServerControlMessage
),
27 log
: log
.With(zap
.String("server", "smtp")),
30 return server
.controlChan
33 type smtpServer
struct {
39 controlChan
chan ServerControlMessage
42 func (server
*smtpServer
) run() {
43 if !server
.loadTLSConfig() {
47 addr
:= fmt
.Sprintf(":%d", server
.config
.SMTPPort
)
48 server
.log
.Info("starting server", zap
.String("address", addr
))
50 l
, err
:= net
.Listen("tcp", addr
)
52 server
.log
.Error("listen", zap
.Error(err
))
53 server
.controlChan
<- ServerControlFatalError
57 connChan
:= make(chan net
.Conn
)
58 go RunAcceptLoop(l
, connChan
, server
.log
)
60 reloadChan
:= CreateReloadSignal()
65 if !server
.loadTLSConfig() {
68 case conn
, ok
:= <-connChan
:
70 go smtp
.AcceptConnection(conn
, server
, server
.log
)
78 func (server
*smtpServer
) loadTLSConfig() bool {
80 server
.tlsConfig
, err
= server
.config
.GetTLSConfig()
82 server
.log
.Error("failed to configure TLS", zap
.Error(err
))
83 server
.controlChan
<- ServerControlFatalError
86 server
.log
.Info("loaded TLS config")
90 func (server
*smtpServer
) Name() string {
91 return server
.config
.Hostname
94 func (server
*smtpServer
) TLSConfig() *tls
.Config
{
95 return server
.tlsConfig
98 func (server
*smtpServer
) VerifyAddress(addr mail
.Address
) smtp
.ReplyLine
{
99 if server
.maildropForAddress(addr
) == "" {
100 return smtp
.ReplyBadMailbox
105 func (server
*smtpServer
) OnEHLO() *smtp
.ReplyLine
{
109 func (server
*smtpServer
) OnMessageDelivered(en smtp
.Envelope
) *smtp
.ReplyLine
{
110 maildrop
:= server
.maildropForAddress(en
.RcptTo
[0])
113 return &smtp
.ReplyBadMailbox
116 f
, err
:= os
.Create(path
.Join(maildrop
, en
.ID
+".msg"))
119 return &smtp
.ReplyBadMailbox
122 smtp
.WriteEnvelopeForDelivery(f
, en
)
127 func (server
*smtpServer
) maildropForAddress(addr mail
.Address
) string {
128 domainIdx
:= strings
.LastIndex(addr
.Address
, "@")
133 domain
:= addr
.Address
[domainIdx
+1:]
135 for _
, s
:= range server
.config
.Servers
{
136 if domain
== s
.Domain
{
137 return s
.MaildropPath