From faa7d3b6474a271469d6519cc00c63c1f2dc448b Mon Sep 17 00:00:00 2001 From: Willy Kloucek Date: Tue, 23 Aug 2022 14:29:04 +0200 Subject: [PATCH] add config options for mail encryption and authentication --- ...mail-authentication-encryption-settings.md | 10 +++ .../examples/ocis_traefik/docker-compose.yml | 3 +- .../notifications/pkg/channels/channels.go | 65 ++++++++++++++++--- services/notifications/pkg/config/config.go | 13 ++-- .../pkg/config/defaults/defaultconfig.go | 8 ++- 5 files changed, 80 insertions(+), 19 deletions(-) create mode 100644 changelog/unreleased/enhancement-mail-authentication-encryption-settings.md diff --git a/changelog/unreleased/enhancement-mail-authentication-encryption-settings.md b/changelog/unreleased/enhancement-mail-authentication-encryption-settings.md new file mode 100644 index 0000000000..1148c126aa --- /dev/null +++ b/changelog/unreleased/enhancement-mail-authentication-encryption-settings.md @@ -0,0 +1,10 @@ +Enhancement: Add configuration options for mail authentication and encryption + +We've added configuration options to configure the authentication and encryption +for sending mails in the notifications service. + +Furthermore there is now a distinguished configuration option for the username to use +for authentication against the mail server. This allows you to customize the sender address +to your liking. For example sender addresses like `my oCIS instance ` are now possible, too. + +https://github.com/owncloud/ocis/pull/4443 diff --git a/deployments/examples/ocis_traefik/docker-compose.yml b/deployments/examples/ocis_traefik/docker-compose.yml index 38e1405947..1b37ca17aa 100644 --- a/deployments/examples/ocis_traefik/docker-compose.yml +++ b/deployments/examples/ocis_traefik/docker-compose.yml @@ -68,7 +68,8 @@ services: # email server (in this case inbucket acts as mail catcher) NOTIFICATIONS_SMTP_HOST: inbucket NOTIFICATIONS_SMTP_PORT: 2500 - NOTIFICATIONS_SMTP_SENDER: notifications@${OCIS_DOMAIN:-ocis.owncloud.test} + NOTIFICATIONS_SMTP_SENDER: oCIS notifications + NOTIFICATIONS_SMTP_USERNAME: notifications@${OCIS_DOMAIN:-ocis.owncloud.test} NOTIFICATIONS_SMTP_INSECURE: true # the mail catcher uses self signed certificates volumes: - ocis-config:/etc/ocis diff --git a/services/notifications/pkg/channels/channels.go b/services/notifications/pkg/channels/channels.go index 896dc8afcf..0612939980 100644 --- a/services/notifications/pkg/channels/channels.go +++ b/services/notifications/pkg/channels/channels.go @@ -4,6 +4,7 @@ package channels import ( "context" "crypto/tls" + "strings" gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" groups "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" @@ -45,6 +46,59 @@ type Mail struct { logger log.Logger } +func (m Mail) getMailClient() (*mail.SMTPClient, error) { + server := mail.NewSMTPClient() + server.Host = m.conf.Notifications.SMTP.Host + server.Port = m.conf.Notifications.SMTP.Port + server.Username = m.conf.Notifications.SMTP.Username + if server.Username == "" { + // compatibility fallback + server.Username = m.conf.Notifications.SMTP.Sender + } + server.Password = m.conf.Notifications.SMTP.Password + if server.TLSConfig == nil { + server.TLSConfig = &tls.Config{} + } + server.TLSConfig.InsecureSkipVerify = m.conf.Notifications.SMTP.Insecure + + switch strings.ToLower(m.conf.Notifications.SMTP.Authentication) { + case "login": + server.Authentication = mail.AuthLogin + case "plain": + server.Authentication = mail.AuthPlain + case "crammd5": + server.Authentication = mail.AuthCRAMMD5 + case "none": + server.Authentication = mail.AuthNone + default: + return nil, errors.New("unknown mail authentication method") + } + + switch strings.ToLower(m.conf.Notifications.SMTP.Encryption) { + case "tls": + server.Encryption = mail.EncryptionTLS + server.TLSConfig.ServerName = m.conf.Notifications.SMTP.Host + case "starttls": + server.Encryption = mail.EncryptionSTARTTLS + server.TLSConfig.ServerName = m.conf.Notifications.SMTP.Host + case "ssl": + server.Encryption = mail.EncryptionSSL + case "ssltls": + server.Encryption = mail.EncryptionSSLTLS + case "none": + server.Encryption = mail.EncryptionNone + default: + return nil, errors.New("unknown mail encryption method") + } + + smtpClient, err := server.Connect() + if err != nil { + return nil, err + } + + return smtpClient, nil +} + // SendMessage sends a message to all given users. func (m Mail) SendMessage(userIDs []string, msg string) error { if m.conf.Notifications.SMTP.Host == "" { @@ -56,22 +110,13 @@ func (m Mail) SendMessage(userIDs []string, msg string) error { return err } - server := mail.NewSMTPClient() - server.Host = m.conf.Notifications.SMTP.Host - server.Port = m.conf.Notifications.SMTP.Port - server.Username = m.conf.Notifications.SMTP.Sender - server.Password = m.conf.Notifications.SMTP.Password - server.TLSConfig = &tls.Config{InsecureSkipVerify: m.conf.Notifications.SMTP.Insecure} - - smtpClient, err := server.Connect() + smtpClient, err := m.getMailClient() if err != nil { return err } email := mail.NewMSG() - email.SetFrom(m.conf.Notifications.SMTP.Sender).AddTo(to...) - email.SetBody(mail.TextPlain, msg) return email.Send(smtpClient) diff --git a/services/notifications/pkg/config/config.go b/services/notifications/pkg/config/config.go index ba23d12c61..849f1ac1ff 100644 --- a/services/notifications/pkg/config/config.go +++ b/services/notifications/pkg/config/config.go @@ -30,11 +30,14 @@ type Notifications struct { // SMTP combines the smtp configuration options. type SMTP struct { - Host string `yaml:"smtp_host" env:"NOTIFICATIONS_SMTP_HOST" desc:"SMTP host to connect to."` - Port int `yaml:"smtp_port" env:"NOTIFICATIONS_SMTP_PORT" desc:"Port of the SMTP host to connect to."` - Sender string `yaml:"smtp_sender" env:"NOTIFICATIONS_SMTP_SENDER" desc:"Sender of emails that will be sent."` - Password string `yaml:"smtp_password" env:"NOTIFICATIONS_SMTP_PASSWORD" desc:"Password of the SMTP host to connect to."` - Insecure bool `yaml:"insecure" env:"NOTIFICATIONS_SMTP_INSECURE" desc:"Allow insecure connections to the SMTP server."` + Host string `yaml:"smtp_host" env:"NOTIFICATIONS_SMTP_HOST" desc:"SMTP host to connect to."` + Port int `yaml:"smtp_port" env:"NOTIFICATIONS_SMTP_PORT" desc:"Port of the SMTP host to connect to."` + Sender string `yaml:"smtp_sender" env:"NOTIFICATIONS_SMTP_SENDER" desc:"Sender address of emails that will be sent."` + Username string `yaml:"smtp_username" env:"NOTIFICATIONS_SMTP_USERNAME" desc:"Username for the SMTP host to connect to."` + Password string `yaml:"smtp_password" env:"NOTIFICATIONS_SMTP_PASSWORD" desc:"Password for the SMTP host to connect to."` + Insecure bool `yaml:"insecure" env:"NOTIFICATIONS_SMTP_INSECURE" desc:"Allow insecure connections to the SMTP server."` + Authentication string `yaml:"smtp_authentication" env:"NOTIFICATIONS_SMTP_AUTHENTICATION" desc:"Authentication method for the SMTP communication. Possible values are 'login', 'plain', 'crammd5', 'none'"` + Encryption string `yaml:"smtp_encryption" env:"NOTIFICATIONS_SMTP_ENCRYPTION" desc:"Encryption method for the SMTP communication. Possible values are 'starttls', 'ssl', 'ssltls', 'tls' and 'none'."` } // Events combines the configuration options for the event bus. diff --git a/services/notifications/pkg/config/defaults/defaultconfig.go b/services/notifications/pkg/config/defaults/defaultconfig.go index acd443345b..849592926c 100644 --- a/services/notifications/pkg/config/defaults/defaultconfig.go +++ b/services/notifications/pkg/config/defaults/defaultconfig.go @@ -24,9 +24,11 @@ func DefaultConfig() *config.Config { }, Notifications: config.Notifications{ SMTP: config.SMTP{ - Host: "", - Port: 1025, - Sender: "noreply@example.com", + Host: "", + Port: 1025, + Sender: "ownCloud ", + Authentication: "none", + Encryption: "none", }, Events: config.Events{ Endpoint: "127.0.0.1:9233",