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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
|
||||||
"net/mail"
|
"net/mail"
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
"os"
|
"os"
|
||||||
|
@ -54,6 +54,10 @@ func processCampaign(c *models.Campaign) {
|
||||||
if c.SMTP.Username != "" && c.SMTP.Password != "" {
|
if c.SMTP.Username != "" && c.SMTP.Password != "" {
|
||||||
auth = smtp.PlainAuth("", c.SMTP.Username, c.SMTP.Password, strings.Split(c.SMTP.Host, ":")[0])
|
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)
|
f, err := mail.ParseAddress(c.SMTP.FromAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
|
@ -110,14 +114,23 @@ func processCampaign(c *models.Campaign) {
|
||||||
Logger.Println("Creating email using template")
|
Logger.Println("Creating email using template")
|
||||||
e.To = []string{t.Email}
|
e.To = []string{t.Email}
|
||||||
Logger.Printf("Sending Email to %s\n", 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 {
|
if err != nil {
|
||||||
Logger.Println(err)
|
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)
|
err = t.UpdateStatus(models.ERROR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
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 {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
}
|
}
|
||||||
|
@ -143,6 +156,14 @@ func SendTestEmail(s *models.SendTestEmailRequest) error {
|
||||||
Subject: s.Template.Subject,
|
Subject: s.Template.Subject,
|
||||||
From: s.SMTP.FromAddress,
|
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)
|
f, err := mail.ParseAddress(s.SMTP.FromAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
|
@ -186,7 +207,7 @@ func SendTestEmail(s *models.SendTestEmailRequest) error {
|
||||||
e.Subject = string(subjBuff.Bytes())
|
e.Subject = string(subjBuff.Bytes())
|
||||||
e.To = []string{s.Email}
|
e.To = []string{s.Email}
|
||||||
Logger.Printf("Sending Email to %s\n", 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 {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
// For now, let's split the error and return
|
// For now, let's split the error and return
|
||||||
|
@ -196,86 +217,3 @@ func SendTestEmail(s *models.SendTestEmailRequest) error {
|
||||||
}
|
}
|
||||||
return err
|
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