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) OnEHLO() *smtp.ReplyLine {
102 func (server *smtpServer) OnMessageDelivered(en smtp.Envelope) *smtp.ReplyLine {
103 maildrop := server.maildropForAddress(en.RcptTo[0])
106 return &smtp.ReplyBadMailbox
109 f, err := os.Create(path.Join(maildrop, en.ID+".msg"))
112 return &smtp.ReplyBadMailbox
115 smtp.WriteEnvelopeForDelivery(f, en)
120 func (server *smtpServer) maildropForAddress(addr mail.Address) string {
121 domain := smtp.DomainForAddress(addr)
122 for _, s := range server.config.Servers {
123 if domain == s.Domain {
124 return s.MaildropPath