Port 465 requires SSL/TLS from the beinging, aka not using STARTTLS.
If you use the smtp.Sendmail() function it fails with io.EOF, very
cryptic. I searched the list for other people experiencing this issue
and found this thread[1]. At the end the suggestion is exactly the
function below. Rewrite smtp.Sendmail() that uses tls.Dial(). So I
wrote my own SendMail() function that dials the server with
tls.Dial().
func SendMailSSL(host string, port uint, auth smtp.Auth, from string,
to []string, msg []byte) (err error) {
serverAddr := fmt.Sprintf("%s:%d", host, port)
conn, err := tls.Dial("tcp", serverAddr, nil)
if err != nil {
log.Println("Error Dialing", err)
return err
}
c, err := smtp.NewClient(conn, host)
if err != nil {
log.Println("Error SMTP connection", err)
return err
}
if auth != nil {
if ok, _ := c.Extension("AUTH"); ok {
if err = c.Auth(auth); err != nil {
log.Println("Error during AUTH", err)
return err
}
}
}
if err = c.Mail(from); err != nil {
return err
}
for _, addr := range to {
if err = c.Rcpt(addr); err != nil {
return err
}
}
w, err := c.Data()
if err != nil {
return err
}
_, err = w.Write(msg)
if err != nil {
return err
}
err = w.Close()
if err != nil {
return err
}
return c.Quit()
}
Now It doesn't fail with a cryptic error, but with "unencrypted
connection" and this error is being generated here[2] by
smtp.plainAuth.Start(). The smtp.Client doesn't know that the net.Conn
is a tls.Conn so smtp.plainAuth thinks the connection is unencrypted.
Would adding in a type check in smtp.NewClient()[3] be a suitable solution?
c := &Client{Text: text, conn: conn, serverName: host}
+if _, ok := conn.(*tls.Conn); ok {
+ c.tls = true
+}
err = c.ehlo()
[1]
http://code.google.com/p/go/source/browse/src/pkg/net/smtp/auth.go?name=release-branch.go1#56
[2]
https://groups.google.com/forum/?fromgroups=#!searchin/golang-nuts/smtp$20ssl/golang-nuts/lnRrEjI14ro/cd0NonOiqN8J
[3]
http://code.google.com/p/go/source/browse/src/pkg/net/smtp/smtp.go?name=release-branch.go1#51