12 "github.com/uber-go/zap"
14 "src.bluestatic.org/mailpopbox/smtp"
17 func runSMTPServer(config Config, log zap.Logger) <-chan error {
21 log: log.With(zap.String("server", "smtp")),
27 type smtpServer struct {
36 func (server *smtpServer) run() {
38 server.tlsConfig, err = server.config.GetTLSConfig()
40 server.log.Error("failed to configure TLS", zap.Error(err))
44 addr := fmt.Sprintf(":%d", server.config.SMTPPort)
45 server.log.Info("starting server", zap.String("address", addr))
47 l, err := net.Listen("tcp", addr)
49 server.log.Error("listen", zap.Error(err))
55 conn, err := l.Accept()
57 server.log.Error("accept", zap.Error(err))
62 go smtp.AcceptConnection(conn, server, server.log)
66 func (server *smtpServer) Name() string {
67 return server.config.Hostname
70 func (server *smtpServer) TLSConfig() *tls.Config {
71 return server.tlsConfig
74 func (server *smtpServer) VerifyAddress(addr mail.Address) smtp.ReplyLine {
75 if server.maildropForAddress(addr) == "" {
76 return smtp.ReplyBadMailbox
81 func (server *smtpServer) OnEHLO() *smtp.ReplyLine {
85 func (server *smtpServer) OnMessageDelivered(en smtp.Envelope) *smtp.ReplyLine {
86 maildrop := server.maildropForAddress(en.RcptTo[0])
89 return &smtp.ReplyBadMailbox
92 f, err := os.Create(path.Join(maildrop, en.ID+".msg"))
95 return &smtp.ReplyBadMailbox
98 smtp.WriteEnvelopeForDelivery(f, en)
103 func (server *smtpServer) maildropForAddress(addr mail.Address) string {
104 domainIdx := strings.LastIndex(addr.Address, "@")
109 domain := addr.Address[domainIdx+1:]
111 for _, s := range server.config.Servers {
112 if domain == s.Domain {
113 return s.MaildropPath