Files
mailgoserver/internal/smtpserver/server.go
T
2026-08-12 12:56:22 +01:00

59 lines
2.0 KiB
Go

package smtpserver
import (
"crypto/tls"
"strings"
"time"
"github.com/emersion/go-smtp"
"gopkg.in/ini.v1"
)
// ResolveBanner mirrors CustomSMTP's server_banner handling (the '""' literal-quotes
// convention for "explicitly empty"). go-smtp's greeting is always
// "220 <Domain> ESMTP Service Ready" with no hook to drop the " ESMTP Service Ready"
// suffix the way aiosmtpd's raw __ident__ override can — so when no custom banner is
// configured, this falls back to heloHostname (a normal, protocol-correct greeting)
// rather than Python's degenerate literally-empty banner. This is a disclosed, cosmetic
// interface deviation: no test tooling in this project inspects the SMTP banner text.
func ResolveBanner(cfg *ini.File, heloHostname string) string {
raw := cfg.Section("Server").Key("server_banner").String()
if raw == `""` {
raw = ""
}
raw = strings.TrimSpace(raw)
if raw == "" {
return heloHostname
}
return raw
}
// NewPlainServer mirrors server_runner.py's PlainController: no TLS context at all, so
// STARTTLS is never offered, and AUTH is advertised and usable in plaintext
// (auth_require_tls=False).
func NewPlainServer(backend *Backend, addr, banner string) *smtp.Server {
s := smtp.NewServer(backend)
s.Addr = addr
s.Domain = banner
s.AllowInsecureAuth = true
s.ReadTimeout = 5 * time.Minute
s.WriteTimeout = 5 * time.Minute
return s
}
// NewTLSServer mirrors server_runner.py's TLSController: implicit/direct TLS (like
// SMTPS on port 465) — the whole connection is encrypted from the first byte, not
// STARTTLS-negotiated. Call ListenAndServeTLS (not ListenAndServe) to run it.
func NewTLSServer(backend *Backend, addr, banner string, tlsConfig *tls.Config) *smtp.Server {
s := smtp.NewServer(backend)
s.Addr = addr
s.Domain = banner
s.TLSConfig = tlsConfig
// The session is always already TLS on this listener, so AUTH is always allowed
// either way (auth_require_tls=True in Python, which is trivially satisfied here).
s.AllowInsecureAuth = true
s.ReadTimeout = 5 * time.Minute
s.WriteTimeout = 5 * time.Minute
return s
}