|
@@ -67,22 +67,53 @@ func processMailQueue() {
|
|
|
}
|
|
|
|
|
|
// sendMail allows mail with self-signed certificates.
|
|
|
-func sendMail(hostAddressWithPort string, auth smtp.Auth, from string, recipients []string, msgContent []byte) error {
|
|
|
- client, err := smtp.Dial(hostAddressWithPort)
|
|
|
+func sendMail(settings *setting.Mailer, from string, recipients []string, msgContent []byte) error {
|
|
|
+ host, port, err := net.SplitHostPort(settings.Host)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- host, _, _ := net.SplitHostPort(hostAddressWithPort)
|
|
|
- tlsConn := &tls.Config{
|
|
|
- InsecureSkipVerify: true,
|
|
|
+ if len(port) == 0 {
|
|
|
+ port = "587"
|
|
|
+ }
|
|
|
+
|
|
|
+ tlsconfig := &tls.Config{
|
|
|
+ InsecureSkipVerify: settings.SkipVerify,
|
|
|
ServerName: host,
|
|
|
}
|
|
|
- if err = client.StartTLS(tlsConn); err != nil {
|
|
|
+
|
|
|
+ var conn net.Conn
|
|
|
+ if conn, err = net.Dial("tcp", net.JoinHostPort(host, port)); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer conn.Close()
|
|
|
+
|
|
|
+ connection_secure := false
|
|
|
+ // Start TLS directly if the port ends with 465 (SMTPS protocol)
|
|
|
+ if strings.HasSuffix(port, "465") {
|
|
|
+ conn = tls.Client(conn, tlsconfig)
|
|
|
+ connection_secure = true
|
|
|
+ }
|
|
|
+
|
|
|
+ var client *smtp.Client
|
|
|
+ if client, err = smtp.NewClient(conn, host); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- if ok, _ := client.Extension("AUTH"); ok && auth != nil {
|
|
|
+ // If not using SMTPS, alway use STARTTLS if available
|
|
|
+ has_starttls, _ := client.Extension("STARTTLS")
|
|
|
+ if !connection_secure && has_starttls {
|
|
|
+ if err = client.StartTLS(tlsconfig); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ auth_available, _ := client.Extension("AUTH")
|
|
|
+
|
|
|
+ // Possible improvement: only plain authentication is now available.
|
|
|
+ // Maybe in future CRAM MD5 as well?
|
|
|
+ if auth_available && len(settings.User) > 0 {
|
|
|
+ auth := smtp.PlainAuth("", settings.User, settings.Passwd, host)
|
|
|
if err = client.Auth(auth); err != nil {
|
|
|
return err
|
|
|
}
|
|
@@ -116,7 +147,6 @@ func sendMail(hostAddressWithPort string, auth smtp.Auth, from string, recipient
|
|
|
// Direct Send mail message
|
|
|
func Send(msg *Message) (int, error) {
|
|
|
log.Trace("Sending mails to: %s", strings.Join(msg.To, "; "))
|
|
|
- host := strings.Split(setting.MailService.Host, ":")
|
|
|
|
|
|
// get message body
|
|
|
content := msg.Content()
|
|
@@ -127,17 +157,12 @@ func Send(msg *Message) (int, error) {
|
|
|
return 0, fmt.Errorf("empty email body")
|
|
|
}
|
|
|
|
|
|
- var auth smtp.Auth
|
|
|
- if len(setting.MailService.Passwd) > 0 {
|
|
|
- auth = smtp.PlainAuth("", setting.MailService.User, setting.MailService.Passwd, host[0])
|
|
|
- }
|
|
|
-
|
|
|
if msg.Massive {
|
|
|
// send mail to multiple emails one by one
|
|
|
num := 0
|
|
|
for _, to := range msg.To {
|
|
|
body := []byte("To: " + to + "\r\n" + content)
|
|
|
- err := sendMail(setting.MailService.Host, auth, msg.From, []string{to}, body)
|
|
|
+ err := sendMail(setting.MailService, msg.From, []string{to}, body)
|
|
|
if err != nil {
|
|
|
return num, err
|
|
|
}
|
|
@@ -148,7 +173,7 @@ func Send(msg *Message) (int, error) {
|
|
|
body := []byte("To: " + strings.Join(msg.To, ";") + "\r\n" + content)
|
|
|
|
|
|
// send to multiple emails in one message
|
|
|
- err := sendMail(setting.MailService.Host, auth, msg.From, msg.To, body)
|
|
|
+ err := sendMail(setting.MailService, msg.From, msg.To, body)
|
|
|
if err != nil {
|
|
|
return 0, err
|
|
|
} else {
|