mirror of https://github.com/gophish/gophish
Handling SMTP TLS via email.SendWithTLS
parent
80333a93ec
commit
26577bc3c3
112
worker/worker.go
112
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()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue