fix(notifier): use sane default connection timeout (#2273)
parent
e2ebdb7e41
commit
c0ebe3eb8c
|
@ -541,20 +541,39 @@ notifier:
|
||||||
## - validate the SMTP server x509 certificate during the TLS handshake against the hosts trusted certificates
|
## - validate the SMTP server x509 certificate during the TLS handshake against the hosts trusted certificates
|
||||||
## (configure in tls section)
|
## (configure in tls section)
|
||||||
smtp:
|
smtp:
|
||||||
username: test
|
## The SMTP host to connect to.
|
||||||
## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
|
|
||||||
password: password
|
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
|
|
||||||
|
## The port to connect to the SMTP host on.
|
||||||
port: 1025
|
port: 1025
|
||||||
|
|
||||||
|
## The connection timeout.
|
||||||
|
timeout: 5s
|
||||||
|
|
||||||
|
## The username used for SMTP authentication.
|
||||||
|
username: test
|
||||||
|
|
||||||
|
## The password used for SMTP authentication.
|
||||||
|
## Can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
|
||||||
|
password: password
|
||||||
|
|
||||||
|
## The address to send the email FROM.
|
||||||
sender: admin@example.com
|
sender: admin@example.com
|
||||||
|
|
||||||
## HELO/EHLO Identifier. Some SMTP Servers may reject the default of localhost.
|
## HELO/EHLO Identifier. Some SMTP Servers may reject the default of localhost.
|
||||||
identifier: localhost
|
identifier: localhost
|
||||||
|
|
||||||
## Subject configuration of the emails sent. {title} is replaced by the text from the notifier.
|
## Subject configuration of the emails sent. {title} is replaced by the text from the notifier.
|
||||||
subject: "[Authelia] {title}"
|
subject: "[Authelia] {title}"
|
||||||
|
|
||||||
## This address is used during the startup check to verify the email configuration is correct.
|
## This address is used during the startup check to verify the email configuration is correct.
|
||||||
## It's not important what it is except if your email server only allows local delivery.
|
## It's not important what it is except if your email server only allows local delivery.
|
||||||
startup_check_address: test@authelia.com
|
startup_check_address: test@authelia.com
|
||||||
|
|
||||||
|
## By default we require some form of TLS. This disables this check though is not advised.
|
||||||
disable_require_tls: false
|
disable_require_tls: false
|
||||||
|
|
||||||
|
## Disables sending HTML formatted emails.
|
||||||
disable_html_emails: false
|
disable_html_emails: false
|
||||||
|
|
||||||
tls:
|
tls:
|
||||||
|
@ -569,16 +588,6 @@ notifier:
|
||||||
## Minimum TLS version for either StartTLS or SMTPS.
|
## Minimum TLS version for either StartTLS or SMTPS.
|
||||||
minimum_version: TLS1.2
|
minimum_version: TLS1.2
|
||||||
|
|
||||||
## Sending an email using a Gmail account is as simple as the next section.
|
|
||||||
## You need to create an app password by following: https://support.google.com/accounts/answer/185833?hl=en
|
|
||||||
# smtp:
|
|
||||||
# username: myaccount@gmail.com
|
|
||||||
# ## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
|
|
||||||
# password: yourapppassword
|
|
||||||
# sender: admin@example.com
|
|
||||||
# host: smtp.gmail.com
|
|
||||||
# port: 587
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Identity Providers
|
## Identity Providers
|
||||||
##
|
##
|
||||||
|
|
|
@ -16,10 +16,11 @@ It can be configured as described below.
|
||||||
notifier:
|
notifier:
|
||||||
disable_startup_check: false
|
disable_startup_check: false
|
||||||
smtp:
|
smtp:
|
||||||
username: test
|
|
||||||
password: password
|
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
port: 1025
|
port: 1025
|
||||||
|
timeout: 5s
|
||||||
|
username: test
|
||||||
|
password: password
|
||||||
sender: admin@example.com
|
sender: admin@example.com
|
||||||
identifier: localhost
|
identifier: localhost
|
||||||
subject: "[Authelia] {title}"
|
subject: "[Authelia] {title}"
|
||||||
|
@ -34,27 +35,6 @@ notifier:
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
### username
|
|
||||||
<div markdown="1">
|
|
||||||
type: string
|
|
||||||
{: .label .label-config .label-purple }
|
|
||||||
required: no
|
|
||||||
{: .label .label-config .label-green }
|
|
||||||
</div>
|
|
||||||
|
|
||||||
The username sent for authentication with the SMTP server. Paired with the password.
|
|
||||||
|
|
||||||
### password
|
|
||||||
<div markdown="1">
|
|
||||||
type: string
|
|
||||||
{: .label .label-config .label-purple }
|
|
||||||
required: no
|
|
||||||
{: .label .label-config .label-green }
|
|
||||||
</div>
|
|
||||||
|
|
||||||
The password sent for authentication with the SMTP server. Paired with the username. Can also be defined using a
|
|
||||||
[secret](../secrets.md) which is the recommended for containerized deployments.
|
|
||||||
|
|
||||||
### host
|
### host
|
||||||
<div markdown="1">
|
<div markdown="1">
|
||||||
type: integer
|
type: integer
|
||||||
|
@ -82,6 +62,39 @@ required: yes
|
||||||
|
|
||||||
The port the SMTP service is listening on.
|
The port the SMTP service is listening on.
|
||||||
|
|
||||||
|
### timeout
|
||||||
|
<div markdown="1">
|
||||||
|
type: duration
|
||||||
|
{: .label .label-config .label-purple }
|
||||||
|
default: 5s
|
||||||
|
{: .label .label-config .label-blue }
|
||||||
|
required: no
|
||||||
|
{: .label .label-config .label-green }
|
||||||
|
</div>
|
||||||
|
|
||||||
|
The SMTP connection timeout.
|
||||||
|
|
||||||
|
### username
|
||||||
|
<div markdown="1">
|
||||||
|
type: string
|
||||||
|
{: .label .label-config .label-purple }
|
||||||
|
required: no
|
||||||
|
{: .label .label-config .label-green }
|
||||||
|
</div>
|
||||||
|
|
||||||
|
The username sent for authentication with the SMTP server. Paired with the password.
|
||||||
|
|
||||||
|
### password
|
||||||
|
<div markdown="1">
|
||||||
|
type: string
|
||||||
|
{: .label .label-config .label-purple }
|
||||||
|
required: no
|
||||||
|
{: .label .label-config .label-green }
|
||||||
|
</div>
|
||||||
|
|
||||||
|
The password sent for authentication with the SMTP server. Paired with the username. Can also be defined using a
|
||||||
|
[secret](../secrets.md) which is the recommended for containerized deployments.
|
||||||
|
|
||||||
### sender
|
### sender
|
||||||
<div markdown="1">
|
<div markdown="1">
|
||||||
type: string
|
type: string
|
||||||
|
@ -93,7 +106,7 @@ required: no
|
||||||
The address sent in the FROM header for the email. Basically who the email appears to come from. It should be noted
|
The address sent in the FROM header for the email. Basically who the email appears to come from. It should be noted
|
||||||
that some SMTP servers require the username provided to have access to send from the specific address listed here.
|
that some SMTP servers require the username provided to have access to send from the specific address listed here.
|
||||||
|
|
||||||
### identifer
|
### identifier
|
||||||
<div markdown="1">
|
<div markdown="1">
|
||||||
type: string
|
type: string
|
||||||
{: .label .label-config .label-purple }
|
{: .label .label-config .label-purple }
|
||||||
|
|
|
@ -120,7 +120,7 @@ func getProviders(config *schema.Configuration) (providers middlewares.Providers
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case config.Notifier.SMTP != nil:
|
case config.Notifier.SMTP != nil:
|
||||||
notifier = notification.NewSMTPNotifier(*config.Notifier.SMTP, autheliaCertPool)
|
notifier = notification.NewSMTPNotifier(config.Notifier.SMTP, autheliaCertPool)
|
||||||
case config.Notifier.FileSystem != nil:
|
case config.Notifier.FileSystem != nil:
|
||||||
notifier = notification.NewFileNotifier(*config.Notifier.FileSystem)
|
notifier = notification.NewFileNotifier(*config.Notifier.FileSystem)
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -541,20 +541,39 @@ notifier:
|
||||||
## - validate the SMTP server x509 certificate during the TLS handshake against the hosts trusted certificates
|
## - validate the SMTP server x509 certificate during the TLS handshake against the hosts trusted certificates
|
||||||
## (configure in tls section)
|
## (configure in tls section)
|
||||||
smtp:
|
smtp:
|
||||||
username: test
|
## The SMTP host to connect to.
|
||||||
## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
|
|
||||||
password: password
|
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
|
|
||||||
|
## The port to connect to the SMTP host on.
|
||||||
port: 1025
|
port: 1025
|
||||||
|
|
||||||
|
## The connection timeout.
|
||||||
|
timeout: 5s
|
||||||
|
|
||||||
|
## The username used for SMTP authentication.
|
||||||
|
username: test
|
||||||
|
|
||||||
|
## The password used for SMTP authentication.
|
||||||
|
## Can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
|
||||||
|
password: password
|
||||||
|
|
||||||
|
## The address to send the email FROM.
|
||||||
sender: admin@example.com
|
sender: admin@example.com
|
||||||
|
|
||||||
## HELO/EHLO Identifier. Some SMTP Servers may reject the default of localhost.
|
## HELO/EHLO Identifier. Some SMTP Servers may reject the default of localhost.
|
||||||
identifier: localhost
|
identifier: localhost
|
||||||
|
|
||||||
## Subject configuration of the emails sent. {title} is replaced by the text from the notifier.
|
## Subject configuration of the emails sent. {title} is replaced by the text from the notifier.
|
||||||
subject: "[Authelia] {title}"
|
subject: "[Authelia] {title}"
|
||||||
|
|
||||||
## This address is used during the startup check to verify the email configuration is correct.
|
## This address is used during the startup check to verify the email configuration is correct.
|
||||||
## It's not important what it is except if your email server only allows local delivery.
|
## It's not important what it is except if your email server only allows local delivery.
|
||||||
startup_check_address: test@authelia.com
|
startup_check_address: test@authelia.com
|
||||||
|
|
||||||
|
## By default we require some form of TLS. This disables this check though is not advised.
|
||||||
disable_require_tls: false
|
disable_require_tls: false
|
||||||
|
|
||||||
|
## Disables sending HTML formatted emails.
|
||||||
disable_html_emails: false
|
disable_html_emails: false
|
||||||
|
|
||||||
tls:
|
tls:
|
||||||
|
@ -569,16 +588,6 @@ notifier:
|
||||||
## Minimum TLS version for either StartTLS or SMTPS.
|
## Minimum TLS version for either StartTLS or SMTPS.
|
||||||
minimum_version: TLS1.2
|
minimum_version: TLS1.2
|
||||||
|
|
||||||
## Sending an email using a Gmail account is as simple as the next section.
|
|
||||||
## You need to create an app password by following: https://support.google.com/accounts/answer/185833?hl=en
|
|
||||||
# smtp:
|
|
||||||
# username: myaccount@gmail.com
|
|
||||||
# ## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
|
|
||||||
# password: yourapppassword
|
|
||||||
# sender: admin@example.com
|
|
||||||
# host: smtp.gmail.com
|
|
||||||
# port: 587
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Identity Providers
|
## Identity Providers
|
||||||
##
|
##
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package schema
|
package schema
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
// FileSystemNotifierConfiguration represents the configuration of the notifier writing emails in a file.
|
// FileSystemNotifierConfiguration represents the configuration of the notifier writing emails in a file.
|
||||||
type FileSystemNotifierConfiguration struct {
|
type FileSystemNotifierConfiguration struct {
|
||||||
Filename string `koanf:"filename"`
|
Filename string `koanf:"filename"`
|
||||||
|
@ -7,17 +9,18 @@ type FileSystemNotifierConfiguration struct {
|
||||||
|
|
||||||
// SMTPNotifierConfiguration represents the configuration of the SMTP server to send emails with.
|
// SMTPNotifierConfiguration represents the configuration of the SMTP server to send emails with.
|
||||||
type SMTPNotifierConfiguration struct {
|
type SMTPNotifierConfiguration struct {
|
||||||
Host string `koanf:"host"`
|
Host string `koanf:"host"`
|
||||||
Port int `koanf:"port"`
|
Port int `koanf:"port"`
|
||||||
Username string `koanf:"username"`
|
Timeout time.Duration `koanf:"timeout"`
|
||||||
Password string `koanf:"password"`
|
Username string `koanf:"username"`
|
||||||
Identifier string `koanf:"identifier"`
|
Password string `koanf:"password"`
|
||||||
Sender string `koanf:"sender"`
|
Identifier string `koanf:"identifier"`
|
||||||
Subject string `koanf:"subject"`
|
Sender string `koanf:"sender"`
|
||||||
StartupCheckAddress string `koanf:"startup_check_address"`
|
Subject string `koanf:"subject"`
|
||||||
DisableRequireTLS bool `koanf:"disable_require_tls"`
|
StartupCheckAddress string `koanf:"startup_check_address"`
|
||||||
DisableHTMLEmails bool `koanf:"disable_html_emails"`
|
DisableRequireTLS bool `koanf:"disable_require_tls"`
|
||||||
TLS *TLSConfig `koanf:"tls"`
|
DisableHTMLEmails bool `koanf:"disable_html_emails"`
|
||||||
|
TLS *TLSConfig `koanf:"tls"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifierConfiguration represents the configuration of the notifier to use when sending notifications to users.
|
// NotifierConfiguration represents the configuration of the notifier to use when sending notifications to users.
|
||||||
|
@ -29,6 +32,7 @@ type NotifierConfiguration struct {
|
||||||
|
|
||||||
// DefaultSMTPNotifierConfiguration represents default configuration parameters for the SMTP notifier.
|
// DefaultSMTPNotifierConfiguration represents default configuration parameters for the SMTP notifier.
|
||||||
var DefaultSMTPNotifierConfiguration = SMTPNotifierConfiguration{
|
var DefaultSMTPNotifierConfiguration = SMTPNotifierConfiguration{
|
||||||
|
Timeout: time.Second * 5,
|
||||||
Subject: "[Authelia] {title}",
|
Subject: "[Authelia] {title}",
|
||||||
Identifier: "localhost",
|
Identifier: "localhost",
|
||||||
TLS: &TLSConfig{
|
TLS: &TLSConfig{
|
||||||
|
|
|
@ -232,6 +232,7 @@ var ValidKeys = []string{
|
||||||
// SMTP Notifier Keys.
|
// SMTP Notifier Keys.
|
||||||
"notifier.smtp.host",
|
"notifier.smtp.host",
|
||||||
"notifier.smtp.port",
|
"notifier.smtp.port",
|
||||||
|
"notifier.smtp.timeout",
|
||||||
"notifier.smtp.username",
|
"notifier.smtp.username",
|
||||||
"notifier.smtp.password",
|
"notifier.smtp.password",
|
||||||
"notifier.smtp.identifier",
|
"notifier.smtp.identifier",
|
||||||
|
|
|
@ -42,6 +42,10 @@ func validateSMTPNotifier(configuration *schema.SMTPNotifierConfiguration, valid
|
||||||
validator.Push(fmt.Errorf(errFmtNotifierSMTPNotConfigured, "port"))
|
validator.Push(fmt.Errorf(errFmtNotifierSMTPNotConfigured, "port"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if configuration.Timeout == 0 {
|
||||||
|
configuration.Timeout = schema.DefaultSMTPNotifierConfiguration.Timeout
|
||||||
|
}
|
||||||
|
|
||||||
if configuration.Sender == "" {
|
if configuration.Sender == "" {
|
||||||
validator.Push(fmt.Errorf(errFmtNotifierSMTPNotConfigured, "sender"))
|
validator.Push(fmt.Errorf(errFmtNotifierSMTPNotConfigured, "sender"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -16,34 +17,16 @@ import (
|
||||||
|
|
||||||
// SMTPNotifier a notifier to send emails to SMTP servers.
|
// SMTPNotifier a notifier to send emails to SMTP servers.
|
||||||
type SMTPNotifier struct {
|
type SMTPNotifier struct {
|
||||||
username string
|
configuration *schema.SMTPNotifierConfiguration
|
||||||
password string
|
client *smtp.Client
|
||||||
sender string
|
tlsConfig *tls.Config
|
||||||
identifier string
|
|
||||||
host string
|
|
||||||
port int
|
|
||||||
disableRequireTLS bool
|
|
||||||
address string
|
|
||||||
subject string
|
|
||||||
startupCheckAddress string
|
|
||||||
client *smtp.Client
|
|
||||||
tlsConfig *tls.Config
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSMTPNotifier creates a SMTPNotifier using the notifier configuration.
|
// NewSMTPNotifier creates a SMTPNotifier using the notifier configuration.
|
||||||
func NewSMTPNotifier(configuration schema.SMTPNotifierConfiguration, certPool *x509.CertPool) *SMTPNotifier {
|
func NewSMTPNotifier(configuration *schema.SMTPNotifierConfiguration, certPool *x509.CertPool) *SMTPNotifier {
|
||||||
notifier := &SMTPNotifier{
|
notifier := &SMTPNotifier{
|
||||||
username: configuration.Username,
|
configuration: configuration,
|
||||||
password: configuration.Password,
|
tlsConfig: utils.NewTLSConfig(configuration.TLS, tls.VersionTLS12, certPool),
|
||||||
sender: configuration.Sender,
|
|
||||||
identifier: configuration.Identifier,
|
|
||||||
host: configuration.Host,
|
|
||||||
port: configuration.Port,
|
|
||||||
disableRequireTLS: configuration.DisableRequireTLS,
|
|
||||||
address: fmt.Sprintf("%s:%d", configuration.Host, configuration.Port),
|
|
||||||
subject: configuration.Subject,
|
|
||||||
startupCheckAddress: configuration.StartupCheckAddress,
|
|
||||||
tlsConfig: utils.NewTLSConfig(configuration.TLS, tls.VersionTLS12, certPool),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return notifier
|
return notifier
|
||||||
|
@ -68,7 +51,7 @@ func (n *SMTPNotifier) startTLS() error {
|
||||||
|
|
||||||
logger.Debug("Notifier SMTP STARTTLS completed without error")
|
logger.Debug("Notifier SMTP STARTTLS completed without error")
|
||||||
default:
|
default:
|
||||||
switch n.disableRequireTLS {
|
switch n.configuration.DisableRequireTLS {
|
||||||
case true:
|
case true:
|
||||||
logger.Warn("Notifier SMTP server does not support STARTTLS and SMTP configuration is set to disable the TLS requirement (only useful for unauthenticated emails over plain text)")
|
logger.Warn("Notifier SMTP server does not support STARTTLS and SMTP configuration is set to disable the TLS requirement (only useful for unauthenticated emails over plain text)")
|
||||||
default:
|
default:
|
||||||
|
@ -83,7 +66,7 @@ func (n *SMTPNotifier) startTLS() error {
|
||||||
func (n *SMTPNotifier) auth() error {
|
func (n *SMTPNotifier) auth() error {
|
||||||
logger := logging.Logger()
|
logger := logging.Logger()
|
||||||
// Attempt AUTH if password is specified only.
|
// Attempt AUTH if password is specified only.
|
||||||
if n.password != "" {
|
if n.configuration.Password != "" {
|
||||||
_, ok := n.client.TLSConnectionState()
|
_, ok := n.client.TLSConnectionState()
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("Notifier SMTP client does not support authentication over plain text and the connection is currently plain text")
|
return errors.New("Notifier SMTP client does not support authentication over plain text and the connection is currently plain text")
|
||||||
|
@ -99,11 +82,11 @@ func (n *SMTPNotifier) auth() error {
|
||||||
|
|
||||||
// Adaptively select the AUTH mechanism to use based on what the server advertised.
|
// Adaptively select the AUTH mechanism to use based on what the server advertised.
|
||||||
if utils.IsStringInSlice("PLAIN", mechanisms) {
|
if utils.IsStringInSlice("PLAIN", mechanisms) {
|
||||||
auth = smtp.PlainAuth("", n.username, n.password, n.host)
|
auth = smtp.PlainAuth("", n.configuration.Username, n.configuration.Password, n.configuration.Host)
|
||||||
|
|
||||||
logger.Debug("Notifier SMTP client attempting AUTH PLAIN with server")
|
logger.Debug("Notifier SMTP client attempting AUTH PLAIN with server")
|
||||||
} else if utils.IsStringInSlice("LOGIN", mechanisms) {
|
} else if utils.IsStringInSlice("LOGIN", mechanisms) {
|
||||||
auth = newLoginAuth(n.username, n.password, n.host)
|
auth = newLoginAuth(n.configuration.Username, n.configuration.Password, n.configuration.Host)
|
||||||
|
|
||||||
logger.Debug("Notifier SMTP client attempting AUTH LOGIN with server")
|
logger.Debug("Notifier SMTP client attempting AUTH LOGIN with server")
|
||||||
}
|
}
|
||||||
|
@ -135,7 +118,7 @@ func (n *SMTPNotifier) compose(recipient, subject, body, htmlBody string) error
|
||||||
logger := logging.Logger()
|
logger := logging.Logger()
|
||||||
logger.Debugf("Notifier SMTP client attempting to send email body to %s", recipient)
|
logger.Debugf("Notifier SMTP client attempting to send email body to %s", recipient)
|
||||||
|
|
||||||
if !n.disableRequireTLS {
|
if !n.configuration.DisableRequireTLS {
|
||||||
_, ok := n.client.TLSConnectionState()
|
_, ok := n.client.TLSConnectionState()
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("Notifier SMTP client can't send an email over plain text connection")
|
return errors.New("Notifier SMTP client can't send an email over plain text connection")
|
||||||
|
@ -153,7 +136,7 @@ func (n *SMTPNotifier) compose(recipient, subject, body, htmlBody string) error
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
msg := "Date:" + now.Format(rfc5322DateTimeLayout) + "\n" +
|
msg := "Date:" + now.Format(rfc5322DateTimeLayout) + "\n" +
|
||||||
"From: " + n.sender + "\n" +
|
"From: " + n.configuration.Sender + "\n" +
|
||||||
"To: " + recipient + "\n" +
|
"To: " + recipient + "\n" +
|
||||||
"Subject: " + subject + "\n" +
|
"Subject: " + subject + "\n" +
|
||||||
"MIME-version: 1.0\n" +
|
"MIME-version: 1.0\n" +
|
||||||
|
@ -188,33 +171,40 @@ func (n *SMTPNotifier) compose(recipient, subject, body, htmlBody string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dial the SMTP server with the SMTPNotifier config.
|
// Dial the SMTP server with the SMTPNotifier config.
|
||||||
func (n *SMTPNotifier) dial() error {
|
func (n *SMTPNotifier) dial() (err error) {
|
||||||
logger := logging.Logger()
|
logger := logging.Logger()
|
||||||
logger.Debugf("Notifier SMTP client attempting connection to %s", n.address)
|
logger.Debugf("Notifier SMTP client attempting connection to %s:%d", n.configuration.Host, n.configuration.Port)
|
||||||
|
|
||||||
if n.port == 465 {
|
var (
|
||||||
|
client *smtp.Client
|
||||||
|
conn net.Conn
|
||||||
|
)
|
||||||
|
|
||||||
|
dialer := &net.Dialer{
|
||||||
|
Timeout: n.configuration.Timeout,
|
||||||
|
}
|
||||||
|
|
||||||
|
if n.configuration.Port == 465 {
|
||||||
logger.Infof("Notifier SMTP client using submissions port 465. Make sure the mail server you are connecting to is configured for submissions and not SMTPS.")
|
logger.Infof("Notifier SMTP client using submissions port 465. Make sure the mail server you are connecting to is configured for submissions and not SMTPS.")
|
||||||
|
|
||||||
conn, err := tls.Dial("tcp", n.address, n.tlsConfig)
|
conn, err = tls.DialWithDialer(dialer, "tcp", fmt.Sprintf("%s:%d", n.configuration.Host, n.configuration.Port), n.tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := smtp.NewClient(conn, n.host)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
n.client = client
|
|
||||||
} else {
|
} else {
|
||||||
client, err := smtp.Dial(n.address)
|
conn, err = dialer.Dial("tcp", fmt.Sprintf("%s:%d", n.configuration.Host, n.configuration.Port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
n.client = client
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client, err = smtp.NewClient(conn, n.configuration.Host)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
n.client = client
|
||||||
|
|
||||||
logger.Debug("Notifier SMTP client connected successfully")
|
logger.Debug("Notifier SMTP client connected successfully")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -238,7 +228,7 @@ func (n *SMTPNotifier) StartupCheck() (bool, error) {
|
||||||
|
|
||||||
defer n.cleanup()
|
defer n.cleanup()
|
||||||
|
|
||||||
if err := n.client.Hello(n.identifier); err != nil {
|
if err := n.client.Hello(n.configuration.Identifier); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,11 +240,11 @@ func (n *SMTPNotifier) StartupCheck() (bool, error) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := n.client.Mail(n.sender); err != nil {
|
if err := n.client.Mail(n.configuration.Sender); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := n.client.Rcpt(n.startupCheckAddress); err != nil {
|
if err := n.client.Rcpt(n.configuration.StartupCheckAddress); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +258,7 @@ func (n *SMTPNotifier) StartupCheck() (bool, error) {
|
||||||
// Send is used to send an email to a recipient.
|
// Send is used to send an email to a recipient.
|
||||||
func (n *SMTPNotifier) Send(recipient, title, body, htmlBody string) error {
|
func (n *SMTPNotifier) Send(recipient, title, body, htmlBody string) error {
|
||||||
logger := logging.Logger()
|
logger := logging.Logger()
|
||||||
subject := strings.ReplaceAll(n.subject, "{title}", title)
|
subject := strings.ReplaceAll(n.configuration.Subject, "{title}", title)
|
||||||
|
|
||||||
if err := n.dial(); err != nil {
|
if err := n.dial(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -277,7 +267,7 @@ func (n *SMTPNotifier) Send(recipient, title, body, htmlBody string) error {
|
||||||
// Always execute QUIT at the end once we're connected.
|
// Always execute QUIT at the end once we're connected.
|
||||||
defer n.cleanup()
|
defer n.cleanup()
|
||||||
|
|
||||||
if err := n.client.Hello(n.identifier); err != nil {
|
if err := n.client.Hello(n.configuration.Identifier); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +281,7 @@ func (n *SMTPNotifier) Send(recipient, title, body, htmlBody string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the sender and recipient first.
|
// Set the sender and recipient first.
|
||||||
if err := n.client.Mail(n.sender); err != nil {
|
if err := n.client.Mail(n.configuration.Sender); err != nil {
|
||||||
logger.Debugf("Notifier SMTP failed while sending MAIL FROM (using sender) with error: %s", err)
|
logger.Debugf("Notifier SMTP failed while sending MAIL FROM (using sender) with error: %s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,11 @@ func TestShouldConfigureSMTPNotifierWithTLS11AndDefaultHostname(t *testing.T) {
|
||||||
sv := schema.NewStructValidator()
|
sv := schema.NewStructValidator()
|
||||||
validator.ValidateNotifier(config, sv)
|
validator.ValidateNotifier(config, sv)
|
||||||
|
|
||||||
notifier := NewSMTPNotifier(*config.SMTP, nil)
|
notifier := NewSMTPNotifier(config.SMTP, nil)
|
||||||
|
|
||||||
assert.Equal(t, "smtp.example.com", notifier.tlsConfig.ServerName)
|
assert.Equal(t, "smtp.example.com", notifier.tlsConfig.ServerName)
|
||||||
assert.Equal(t, uint16(tls.VersionTLS11), notifier.tlsConfig.MinVersion)
|
assert.Equal(t, uint16(tls.VersionTLS11), notifier.tlsConfig.MinVersion)
|
||||||
assert.False(t, notifier.tlsConfig.InsecureSkipVerify)
|
assert.False(t, notifier.tlsConfig.InsecureSkipVerify)
|
||||||
assert.Equal(t, "smtp.example.com:25", notifier.address)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldConfigureSMTPNotifierWithServerNameOverrideAndDefaultTLS12(t *testing.T) {
|
func TestShouldConfigureSMTPNotifierWithServerNameOverrideAndDefaultTLS12(t *testing.T) {
|
||||||
|
@ -48,10 +47,9 @@ func TestShouldConfigureSMTPNotifierWithServerNameOverrideAndDefaultTLS12(t *tes
|
||||||
sv := schema.NewStructValidator()
|
sv := schema.NewStructValidator()
|
||||||
validator.ValidateNotifier(config, sv)
|
validator.ValidateNotifier(config, sv)
|
||||||
|
|
||||||
notifier := NewSMTPNotifier(*config.SMTP, nil)
|
notifier := NewSMTPNotifier(config.SMTP, nil)
|
||||||
|
|
||||||
assert.Equal(t, "smtp.golang.org", notifier.tlsConfig.ServerName)
|
assert.Equal(t, "smtp.golang.org", notifier.tlsConfig.ServerName)
|
||||||
assert.Equal(t, uint16(tls.VersionTLS12), notifier.tlsConfig.MinVersion)
|
assert.Equal(t, uint16(tls.VersionTLS12), notifier.tlsConfig.MinVersion)
|
||||||
assert.False(t, notifier.tlsConfig.InsecureSkipVerify)
|
assert.False(t, notifier.tlsConfig.InsecureSkipVerify)
|
||||||
assert.Equal(t, "smtp.example.com:25", notifier.address)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue