diff --git a/config/config.go b/config/config.go index 0b3d887..7657e04 100644 --- a/config/config.go +++ b/config/config.go @@ -35,7 +35,9 @@ type Config struct { // IMAPServerConfig holds settings for the embedded read-only IMAP archive server. type IMAPServerConfig struct { Enabled bool `yaml:"enabled"` - Bind string `yaml:"bind"` // default: "127.0.0.1:1143" + Bind string `yaml:"bind"` // plain: ":1143", TLS: ":993" + TLSCert string `yaml:"tls_cert"` // path to PEM certificate; if set, TLS is enabled + TLSKey string `yaml:"tls_key"` // path to PEM private key } // ServerConfig holds port settings for the main services. diff --git a/internal/imapserver/server.go b/internal/imapserver/server.go index 7b880c6..f77817a 100644 --- a/internal/imapserver/server.go +++ b/internal/imapserver/server.go @@ -9,6 +9,7 @@ package imapserver import ( "bufio" "context" + "crypto/tls" "fmt" "log/slog" "net" @@ -81,12 +82,34 @@ func New( func (s *Server) Start() error { bind := s.cfg.Bind if bind == "" { - bind = "127.0.0.1:1143" + if s.cfg.TLSCert != "" { + bind = ":993" + } else { + bind = "127.0.0.1:1143" + } } - ln, err := net.Listen("tcp", bind) - if err != nil { - return fmt.Errorf("imapserver: listen %s: %w", bind, err) + var ln net.Listener + var err error + if s.cfg.TLSCert != "" && s.cfg.TLSKey != "" { + cert, err := tls.LoadX509KeyPair(s.cfg.TLSCert, s.cfg.TLSKey) + if err != nil { + return fmt.Errorf("imapserver: load TLS cert: %w", err) + } + tlsCfg := &tls.Config{ + Certificates: []tls.Certificate{cert}, + MinVersion: tls.VersionTLS12, + } + ln, err = tls.Listen("tcp", bind, tlsCfg) + if err != nil { + return fmt.Errorf("imapserver: tls listen %s: %w", bind, err) + } + s.logger.Info("IMAP archive server TLS enabled", "addr", bind) + } else { + ln, err = net.Listen("tcp", bind) + if err != nil { + return fmt.Errorf("imapserver: listen %s: %w", bind, err) + } } s.mu.Lock()