From 26577bc3c3f6d9443ce2e8c3483c03e3a37a0bac Mon Sep 17 00:00:00 2001 From: Jordan Wright Date: Fri, 12 Feb 2016 21:24:05 -0600 Subject: [PATCH] Handling SMTP TLS via email.SendWithTLS --- worker/worker.go | 112 +++++++++++------------------------------------ 1 file changed, 25 insertions(+), 87 deletions(-) diff --git a/worker/worker.go b/worker/worker.go index 335be975..fdbdb64f 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -3,9 +3,9 @@ package worker import ( "bytes" "crypto/tls" + "encoding/json" "errors" "log" - "net" "net/mail" "net/smtp" "os" @@ -54,6 +54,10 @@ func processCampaign(c *models.Campaign) { if c.SMTP.Username != "" && c.SMTP.Password != "" { auth = smtp.PlainAuth("", c.SMTP.Username, c.SMTP.Password, strings.Split(c.SMTP.Host, ":")[0]) } + tc := &tls.Config{ + ServerName: c.SMTP.Host, + InsecureSkipVerify: c.SMTP.IgnoreCertErrors, + } f, err := mail.ParseAddress(c.SMTP.FromAddress) if err != nil { Logger.Println(err) @@ -110,14 +114,23 @@ func processCampaign(c *models.Campaign) { Logger.Println("Creating email using template") e.To = []string{t.Email} Logger.Printf("Sending Email to %s\n", t.Email) - err = e.Send(c.SMTP.Host, auth) + err = e.SendWithTLS(c.SMTP.Host, auth, tc) if err != nil { Logger.Println(err) + es := struct { + Error string `json:"error"` + }{ + Error: err.Error(), + } + ej, err := json.Marshal(es) + if err != nil { + Logger.Println(err) + } err = t.UpdateStatus(models.ERROR) if err != nil { Logger.Println(err) } - err = c.AddEvent(models.Event{Email: t.Email, Message: models.EVENT_SENDING_ERROR}) + err = c.AddEvent(models.Event{Email: t.Email, Message: models.EVENT_SENDING_ERROR, Details: string(ej)}) if err != nil { Logger.Println(err) } @@ -143,6 +156,14 @@ func SendTestEmail(s *models.SendTestEmailRequest) error { Subject: s.Template.Subject, From: s.SMTP.FromAddress, } + var auth smtp.Auth + if s.SMTP.Username != "" && s.SMTP.Password != "" { + auth = smtp.PlainAuth("", s.SMTP.Username, s.SMTP.Password, strings.Split(s.SMTP.Host, ":")[0]) + } + t := &tls.Config{ + ServerName: s.SMTP.Host, + InsecureSkipVerify: s.SMTP.IgnoreCertErrors, + } f, err := mail.ParseAddress(s.SMTP.FromAddress) if err != nil { Logger.Println(err) @@ -186,7 +207,7 @@ func SendTestEmail(s *models.SendTestEmailRequest) error { e.Subject = string(subjBuff.Bytes()) e.To = []string{s.Email} Logger.Printf("Sending Email to %s\n", s.Email) - err = sendMail(e, s.SMTP) + err = e.SendWithTLS(s.SMTP.Host, auth, t) if err != nil { Logger.Println(err) // For now, let's split the error and return @@ -196,86 +217,3 @@ func SendTestEmail(s *models.SendTestEmailRequest) error { } return err } - -// sendEmail is a copy of the net/smtp#SendMail function -// that has the option to ignore TLS errors -// TODO: Find a more elegant way (maybe in the email lib?) to do this -func sendMail(e email.Email, s models.SMTP) error { - var auth smtp.Auth - if s.Username != "" && s.Password != "" { - auth = smtp.PlainAuth("", s.Username, s.Password, strings.Split(s.Host, ":")[0]) - } - // Taken from the email library - // Merge the To, Cc, and Bcc fields - to := make([]string, 0, len(e.To)+len(e.Cc)+len(e.Bcc)) - to = append(append(append(to, e.To...), e.Cc...), e.Bcc...) - for i := 0; i < len(to); i++ { - addr, err := mail.ParseAddress(to[i]) - if err != nil { - return err - } - to[i] = addr.Address - } - // Check to make sure there is at least one recipient and one "From" address - if e.From == "" || len(to) == 0 { - return errors.New("Must specify at least one From address and one To address") - } - from, err := mail.ParseAddress(e.From) - if err != nil { - return err - } - msg, err := e.Bytes() - if err != nil { - return err - } - // Taken from the standard library - // https://github.com/golang/go/blob/master/src/net/smtp/smtp.go#L300 - c, err := smtp.Dial(s.Host) - if err != nil { - return err - } - defer c.Close() - if err = c.Hello("localhost"); err != nil { - return err - } - // Use TLS if available - if ok, _ := c.Extension("STARTTLS"); ok { - host, _, _ := net.SplitHostPort(s.Host) - config := &tls.Config{ - ServerName: host, - InsecureSkipVerify: s.IgnoreCertErrors, - } - if err = c.StartTLS(config); err != nil { - return err - } - } - - if auth != nil { - if ok, _ := c.Extension("AUTH"); ok { - if err = c.Auth(auth); err != nil { - return err - } - } - } - if err = c.Mail(from.Address); 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() -}