From b4a6cf4c7842dc9f62c3eec34fbbf947349f729d Mon Sep 17 00:00:00 2001 From: ale <ale@incal.net> Date: Tue, 28 Sep 2021 22:19:08 +0100 Subject: [PATCH] Fix SMTP authentication Provide our own net/smtp.Auth implementation to do AUTH PLAIN without the TLS check. Fixes issue #1. --- protocol/smtp/smtp.go | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/protocol/smtp/smtp.go b/protocol/smtp/smtp.go index 92b931c..f57970a 100644 --- a/protocol/smtp/smtp.go +++ b/protocol/smtp/smtp.go @@ -58,7 +58,7 @@ func (c *Conn) Close() error { } func (c *Conn) SendMail(username, password, from string, to []string, msg []byte) error { - auth := smtp.PlainAuth("", username, password, c.hostname) + auth := newPlainAuth("", username, password, c.hostname) if ok, _ := c.client.Extension("AUTH"); !ok { return errors.New("server does not support AUTH extension") } @@ -86,3 +86,35 @@ func (c *Conn) SendMail(username, password, from string, to []string, msg []byte } return nil } + +// This is almost a copy of net/smtp/auth.go, but without the TLS +// check. The net/smtp package attempts to autodetect TLS usage by +// checking if the net.Conn it got is actually a *tls.Conn. Since we +// wrap our connection in the logging wrapper, this check fails, and +// net/smtp.PlainAuth will refuse to authenticate, thinking the +// connection is unencrypted. +type plainAuth struct { + identity, username, password string + host string +} + +func newPlainAuth(identity, username, password, host string) smtp.Auth { + return &plainAuth{identity, username, password, host} +} + +func (a *plainAuth) Start(server *smtp.ServerInfo) (string, []byte, error) { + // We know we have TLS. + if server.Name != a.host { + return "", nil, errors.New("wrong host name") + } + resp := []byte(a.identity + "\x00" + a.username + "\x00" + a.password) + return "PLAIN", resp, nil +} + +func (a *plainAuth) Next(fromServer []byte, more bool) ([]byte, error) { + if more { + // We've already sent everything. + return nil, errors.New("unexpected server challenge") + } + return nil, nil +} -- GitLab