mirror of
https://github.com/outbackdingo/labca.git
synced 2026-03-22 06:43:23 +00:00
LabCA can optionally be configured to send emails. Until now it was only possible to send to SMTP servers that use a certificate signed by a public root CA (e.g. gmail). Now this can also be an internal server using a LabCA issued certificate, or you can skip TLS verification completely.
113 lines
3.3 KiB
Diff
113 lines
3.3 KiB
Diff
diff --git a/mail/mailer.go b/mail/mailer.go
|
|
index 31ebd40b1..61add3ec2 100644
|
|
--- a/mail/mailer.go
|
|
+++ b/mail/mailer.go
|
|
@@ -2,6 +2,7 @@ package mail
|
|
|
|
import (
|
|
"bytes"
|
|
+ "context"
|
|
"crypto/rand"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
@@ -23,8 +24,11 @@ import (
|
|
"github.com/jmhodges/clock"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
|
|
+ "github.com/letsencrypt/boulder/bdns"
|
|
"github.com/letsencrypt/boulder/core"
|
|
+ berrors "github.com/letsencrypt/boulder/errors"
|
|
blog "github.com/letsencrypt/boulder/log"
|
|
+ "github.com/letsencrypt/boulder/probs"
|
|
)
|
|
|
|
type idGenerator interface {
|
|
@@ -139,6 +143,8 @@ func New(
|
|
username,
|
|
password string,
|
|
rootCAs *x509.CertPool,
|
|
+ insecureSkipVerify bool,
|
|
+ resolver bdns.Client,
|
|
from mail.Address,
|
|
logger blog.Logger,
|
|
stats prometheus.Registerer,
|
|
@@ -154,11 +160,13 @@ func New(
|
|
return &mailerImpl{
|
|
config: config{
|
|
dialer: &dialerImpl{
|
|
- username: username,
|
|
- password: password,
|
|
- server: server,
|
|
- port: port,
|
|
- rootCAs: rootCAs,
|
|
+ username: username,
|
|
+ password: password,
|
|
+ server: server,
|
|
+ port: port,
|
|
+ rootCAs: rootCAs,
|
|
+ insecureSkipVerify: insecureSkipVerify,
|
|
+ dnsClient: resolver,
|
|
},
|
|
log: logger,
|
|
from: from,
|
|
@@ -202,7 +210,7 @@ func (c config) generateMessage(to []string, subject, body string) ([]byte, erro
|
|
fmt.Sprintf("To: %s", strings.Join(addrs, ", ")),
|
|
fmt.Sprintf("From: %s", c.from.String()),
|
|
fmt.Sprintf("Subject: %s", subject),
|
|
- fmt.Sprintf("Date: %s", now.Format(time.RFC822)),
|
|
+ fmt.Sprintf("Date: %s", now.Format(time.RFC1123Z)),
|
|
fmt.Sprintf("Message-Id: <%s.%s.%s>", now.Format("20060102T150405"), mid.String(), c.from.Address),
|
|
"MIME-Version: 1.0",
|
|
"Content-Type: text/plain; charset=UTF-8",
|
|
@@ -259,23 +267,41 @@ func (m *mailerImpl) Connect() (Conn, error) {
|
|
type dialerImpl struct {
|
|
username, password, server, port string
|
|
rootCAs *x509.CertPool
|
|
+ insecureSkipVerify bool
|
|
+ dnsClient bdns.Client
|
|
}
|
|
|
|
func (di *dialerImpl) Dial() (smtpClient, error) {
|
|
- hostport := net.JoinHostPort(di.server, di.port)
|
|
- var conn net.Conn
|
|
- var err error
|
|
- conn, err = tls.Dial("tcp", hostport, &tls.Config{
|
|
- RootCAs: di.rootCAs,
|
|
- })
|
|
+ deadline := time.Now().Add(30 * time.Second)
|
|
+ ctx, cancel := context.WithDeadline(context.Background(), deadline)
|
|
+ defer cancel()
|
|
+
|
|
+ addrs, _, err := di.dnsClient.LookupHost(ctx, di.server)
|
|
if err != nil {
|
|
- return nil, err
|
|
+ problem := probs.DNS("%v")
|
|
+ return nil, problem
|
|
+ }
|
|
+
|
|
+ if len(addrs) == 0 {
|
|
+ return nil, berrors.DNSError("No valid IP addresses found for %s", di.server)
|
|
}
|
|
- client, err := smtp.NewClient(conn, di.server)
|
|
+
|
|
+ tlsconf := &tls.Config{
|
|
+ ServerName: di.server,
|
|
+ }
|
|
+ if di.insecureSkipVerify {
|
|
+ tlsconf.InsecureSkipVerify = true
|
|
+ } else {
|
|
+ tlsconf.RootCAs = di.rootCAs
|
|
+ }
|
|
+
|
|
+ hostport := net.JoinHostPort(addrs[0].String(), di.port)
|
|
+ client, err := smtp.Dial(hostport)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
- auth := smtp.PlainAuth("", di.username, di.password, di.server)
|
|
+ client.StartTLS(tlsconf)
|
|
+ auth := smtp.PlainAuth("", di.username, di.password, addrs[0].String())
|
|
if err = client.Auth(auth); err != nil {
|
|
return nil, err
|
|
}
|