diff --git a/protocol/smtp/smtp.go b/protocol/smtp/smtp.go
index 92b931cdad6133ce5fb947a893a27172217fbe9b..f57970a46c3e52ecaffd81d1eb228b08d234c5f2 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
+}