From 519c44e998bbe3ad05623cf2615e212260d07ec9 Mon Sep 17 00:00:00 2001 From: Aine Date: Sun, 13 Nov 2022 16:07:38 +0200 Subject: [PATCH] support multi-domain certificates --- README.md | 4 ++-- cmd/cmd.go | 4 ++-- config/config.go | 4 ++-- config/types.go | 4 ++-- smtp/manager.go | 27 +++++++++++++++++---------- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 3ad00e1..1dfede3 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,8 @@ env vars * **POSTMOOGLE_PORT** - SMTP port to listen for new emails * **POSTMOOGLE_TLS_PORT** - secure SMTP port to listen for new emails. Requires valid cert and key as well -* **POSTMOOGLE_TLS_CERT** - path to the SSL certificate (chain) of your main domain -* **POSTMOOGLE_TLS_KEY** - path to the SSL certificate's private key of your main domain +* **POSTMOOGLE_TLS_CERT** - space separated list of paths to the SSL certificates (chain) of your domains, note that position in the cert list must match the position of the cert's key in the key list +* **POSTMOOGLE_TLS_KEY** - space separated list of paths to the SSL certificates' private keys of your domains, note that position on the key list must match the position of cert in the cert list * **POSTMOOGLE_TLS_REQUIRED** - require TLS connection, **even** on the non-TLS port (`POSTMOOGLE_PORT`). TLS connections are always required on the TLS port (`POSTMOOGLE_TLS_PORT`) regardless of this setting. * **POSTMOOGLE_DATA_SECRET** - secure key (password) to encrypt account data, must be 16, 24, or 32 bytes long * **POSTMOOGLE_NOENCRYPTION** - disable matrix encryption (libolm) support diff --git a/cmd/cmd.go b/cmd/cmd.go index 6fdd4b9..0550101 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -99,8 +99,8 @@ func initSMTP(cfg *config.Config) { smtpm = smtp.NewManager(&smtp.Config{ Domains: cfg.Domains, Port: cfg.Port, - TLSCert: cfg.TLS.Cert, - TLSKey: cfg.TLS.Key, + TLSCerts: cfg.TLS.Certs, + TLSKeys: cfg.TLS.Keys, TLSPort: cfg.TLS.Port, TLSRequired: cfg.TLS.Required, LogLevel: cfg.LogLevel, diff --git a/config/config.go b/config/config.go index c410ff5..e0eeffd 100644 --- a/config/config.go +++ b/config/config.go @@ -23,8 +23,8 @@ func New() *Config { StatusMsg: env.String("statusmsg", defaultConfig.StatusMsg), Admins: env.Slice("admins"), TLS: TLS{ - Cert: env.String("tls.cert", defaultConfig.TLS.Cert), - Key: env.String("tls.key", defaultConfig.TLS.Key), + Certs: env.Slice("tls.cert"), + Keys: env.Slice("tls.key"), Required: env.Bool("tls.required"), Port: env.String("tls.port", defaultConfig.TLS.Port), }, diff --git a/config/types.go b/config/types.go index f355275..e34c988 100644 --- a/config/types.go +++ b/config/types.go @@ -47,8 +47,8 @@ type DB struct { // TLS config type TLS struct { - Cert string - Key string + Certs []string + Keys []string Port string Required bool } diff --git a/smtp/manager.go b/smtp/manager.go index 3fc98ed..217886d 100644 --- a/smtp/manager.go +++ b/smtp/manager.go @@ -18,8 +18,8 @@ type Config struct { Domains []string Port string - TLSCert string - TLSKey string + TLSCerts []string + TLSKeys []string TLSPort string TLSRequired bool @@ -75,7 +75,7 @@ func NewManager(cfg *Config) *Manager { port: cfg.Port, tlsPort: cfg.TLSPort, } - m.loadTLSConfig(cfg.TLSCert, cfg.TLSKey) + m.loadTLSConfig(cfg.TLSCerts, cfg.TLSKeys) return m } @@ -123,17 +123,24 @@ func (m *Manager) listen(port string, tlsCfg *tls.Config) { } } -func (m *Manager) loadTLSConfig(cert, key string) { - if cert == "" || key == "" { - m.log.Warn("SSL certificate is not provided") +func (m *Manager) loadTLSConfig(certs, keys []string) { + if len(certs) == 0 || len(keys) == 0 { + m.log.Warn("SSL certificates are not provided") return } - tlsCert, err := tls.LoadX509KeyPair(cert, key) - if err != nil { - m.log.Error("cannot load SSL certificate: %v", err) + certificates := make([]tls.Certificate, 0, len(certs)) + for i, path := range certs { + tlsCert, err := tls.LoadX509KeyPair(path, keys[i]) + if err != nil { + m.log.Error("cannot load SSL certificate: %v", err) + } + certificates = append(certificates, tlsCert) + } + if len(certificates) == 0 { return } - m.tlsCfg = &tls.Config{Certificates: []tls.Certificate{tlsCert}} + + m.tlsCfg = &tls.Config{Certificates: certificates} m.smtp.TLSConfig = m.tlsCfg }