mirror of https://github.com/gophish/gophish
parent
dbadac3eca
commit
66c4be3d4f
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
-- +goose Up
|
||||||
|
-- SQL in section 'Up' is executed when this migration is applied
|
||||||
|
CREATE TABLE IF NOT EXISTS headers(
|
||||||
|
id integer primary key auto_increment,
|
||||||
|
`key` varchar(255),
|
||||||
|
`value` varchar(255),
|
||||||
|
`smtp_id` bigint
|
||||||
|
);
|
||||||
|
-- +goose Down
|
||||||
|
-- SQL section 'Down' is executed when this migration is rolled back
|
||||||
|
DROP TABLE headers;
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
-- +goose Up
|
||||||
|
-- SQL in section 'Up' is executed when this migration is applied
|
||||||
|
CREATE TABLE IF NOT EXISTS headers(
|
||||||
|
id integer primary key autoincrement,
|
||||||
|
key varchar(255),
|
||||||
|
value varchar(255),
|
||||||
|
"smtp_id" bigint
|
||||||
|
);
|
||||||
|
-- +goose Down
|
||||||
|
-- SQL section 'Down' is executed when this migration is rolled back
|
||||||
|
DROP TABLE headers;
|
|
@ -189,6 +189,11 @@ func (c *Campaign) getDetails() error {
|
||||||
c.SMTP = SMTP{Name: "[Deleted]"}
|
c.SMTP = SMTP{Name: "[Deleted]"}
|
||||||
Logger.Printf("%s: sending profile not found for campaign\n", err)
|
Logger.Printf("%s: sending profile not found for campaign\n", err)
|
||||||
}
|
}
|
||||||
|
err = db.Where("smtp_id=?", c.SMTP.Id).Find(&c.SMTP.Headers).Error
|
||||||
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
|
Logger.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,6 +246,24 @@ func (s *ModelsSuite) TestPostSMTPNoFrom(c *check.C) {
|
||||||
c.Assert(err, check.Equals, ErrFromAddressNotSpecified)
|
c.Assert(err, check.Equals, ErrFromAddressNotSpecified)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ModelsSuite) TestPostSMTPValidHeader(c *check.C) {
|
||||||
|
smtp := SMTP{
|
||||||
|
Name: "Test SMTP",
|
||||||
|
Host: "1.1.1.1:25",
|
||||||
|
FromAddress: "Foo Bar <foo@example.com>",
|
||||||
|
UserId: 1,
|
||||||
|
Headers: []Header{
|
||||||
|
Header{Key: "Reply-To", Value: "test@example.com"},
|
||||||
|
Header{Key: "X-Mailer", Value: "gophish"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = PostSMTP(&smtp)
|
||||||
|
c.Assert(err, check.Equals, nil)
|
||||||
|
ss, err := GetSMTPs(1)
|
||||||
|
c.Assert(err, check.Equals, nil)
|
||||||
|
c.Assert(len(ss), check.Equals, 1)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *ModelsSuite) TestPostPage(c *check.C) {
|
func (s *ModelsSuite) TestPostPage(c *check.C) {
|
||||||
html := `<html>
|
html := `<html>
|
||||||
<head></head>
|
<head></head>
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SMTP contains the attributes needed to handle the sending of campaign emails
|
// SMTP contains the attributes needed to handle the sending of campaign emails
|
||||||
|
@ -19,9 +21,19 @@ type SMTP struct {
|
||||||
Password string `json:"password,omitempty"`
|
Password string `json:"password,omitempty"`
|
||||||
FromAddress string `json:"from_address"`
|
FromAddress string `json:"from_address"`
|
||||||
IgnoreCertErrors bool `json:"ignore_cert_errors"`
|
IgnoreCertErrors bool `json:"ignore_cert_errors"`
|
||||||
|
Headers []Header `json:"headers"`
|
||||||
ModifiedDate time.Time `json:"modified_date"`
|
ModifiedDate time.Time `json:"modified_date"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Header contains the fields and methods for a sending profile to have
|
||||||
|
// custom headers
|
||||||
|
type Header struct {
|
||||||
|
Id int64 `json:"-"`
|
||||||
|
SMTPId int64 `json:"-"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
// ErrFromAddressNotSpecified is thrown when there is no "From" address
|
// ErrFromAddressNotSpecified is thrown when there is no "From" address
|
||||||
// specified in the SMTP configuration
|
// specified in the SMTP configuration
|
||||||
var ErrFromAddressNotSpecified = errors.New("No From Address specified")
|
var ErrFromAddressNotSpecified = errors.New("No From Address specified")
|
||||||
|
@ -70,8 +82,16 @@ func GetSMTPs(uid int64) ([]SMTP, error) {
|
||||||
err := db.Where("user_id=?", uid).Find(&ss).Error
|
err := db.Where("user_id=?", uid).Find(&ss).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
}
|
|
||||||
return ss, err
|
return ss, err
|
||||||
|
}
|
||||||
|
for i, _ := range ss {
|
||||||
|
err = db.Where("smtp_id=?", ss[i].Id).Find(&ss[i].Headers).Error
|
||||||
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
|
Logger.Println(err)
|
||||||
|
return ss, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ss, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSMTP returns the SMTP, if it exists, specified by the given id and user_id.
|
// GetSMTP returns the SMTP, if it exists, specified by the given id and user_id.
|
||||||
|
@ -81,6 +101,11 @@ func GetSMTP(id int64, uid int64) (SMTP, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
}
|
}
|
||||||
|
err = db.Where("smtp_id=?", s.Id).Find(&s.Headers).Error
|
||||||
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
|
Logger.Println(err)
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +115,11 @@ func GetSMTPByName(n string, uid int64) (SMTP, error) {
|
||||||
err := db.Where("user_id=? and name=?", uid, n).Find(&s).Error
|
err := db.Where("user_id=? and name=?", uid, n).Find(&s).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
err = db.Where("smtp_id=?", s.Id).Find(&s.Headers).Error
|
||||||
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
|
Logger.Println(err)
|
||||||
}
|
}
|
||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
@ -106,6 +136,15 @@ func PostSMTP(s *SMTP) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
}
|
}
|
||||||
|
// Save custom headers
|
||||||
|
for i, _ := range s.Headers {
|
||||||
|
s.Headers[i].SMTPId = s.Id
|
||||||
|
err := db.Save(&s.Headers[i]).Error
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,12 +160,32 @@ func PutSMTP(s *SMTP) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
}
|
}
|
||||||
|
// Delete all custom headers, and replace with new ones
|
||||||
|
err = db.Where("smtp_id=?", s.Id).Delete(&Header{}).Error
|
||||||
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
|
Logger.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, _ := range s.Headers {
|
||||||
|
s.Headers[i].SMTPId = s.Id
|
||||||
|
err := db.Save(&s.Headers[i]).Error
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteSMTP deletes an existing SMTP in the database.
|
// DeleteSMTP deletes an existing SMTP in the database.
|
||||||
// An error is returned if a SMTP with the given user id and SMTP id is not found.
|
// An error is returned if a SMTP with the given user id and SMTP id is not found.
|
||||||
func DeleteSMTP(id int64, uid int64) error {
|
func DeleteSMTP(id int64, uid int64) error {
|
||||||
|
// Delete all custom headers
|
||||||
|
err = db.Where("smtp_id=?", id).Delete(&Header{}).Error
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
err = db.Where("user_id=?", uid).Delete(SMTP{Id: id}).Error
|
err = db.Where("user_id=?", uid).Delete(SMTP{Id: id}).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
|
|
|
@ -64,6 +64,7 @@ func (t *Template) Validate() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err = template.New("text_template").Parse(t.Text)
|
tmpl, err = template.New("text_template").Parse(t.Text)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -81,6 +82,7 @@ func GetTemplates(uid int64) ([]Template, error) {
|
||||||
return ts, err
|
return ts, err
|
||||||
}
|
}
|
||||||
for i, _ := range ts {
|
for i, _ := range ts {
|
||||||
|
// Get Attachments
|
||||||
err = db.Where("template_id=?", ts[i].Id).Find(&ts[i].Attachments).Error
|
err = db.Where("template_id=?", ts[i].Id).Find(&ts[i].Attachments).Error
|
||||||
if err == nil && len(ts[i].Attachments) == 0 {
|
if err == nil && len(ts[i].Attachments) == 0 {
|
||||||
ts[i].Attachments = make([]Attachment, 0)
|
ts[i].Attachments = make([]Attachment, 0)
|
||||||
|
@ -101,6 +103,8 @@ func GetTemplate(id int64, uid int64) (Template, error) {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
return t, err
|
return t, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get Attachments
|
||||||
err = db.Where("template_id=?", t.Id).Find(&t.Attachments).Error
|
err = db.Where("template_id=?", t.Id).Find(&t.Attachments).Error
|
||||||
if err != nil && err != gorm.ErrRecordNotFound {
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
|
@ -120,6 +124,8 @@ func GetTemplateByName(n string, uid int64) (Template, error) {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
return t, err
|
return t, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get Attachments
|
||||||
err = db.Where("template_id=?", t.Id).Find(&t.Attachments).Error
|
err = db.Where("template_id=?", t.Id).Find(&t.Attachments).Error
|
||||||
if err != nil && err != gorm.ErrRecordNotFound {
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
|
@ -142,6 +148,8 @@ func PostTemplate(t *Template) error {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save every attachment
|
||||||
for i, _ := range t.Attachments {
|
for i, _ := range t.Attachments {
|
||||||
Logger.Println(t.Attachments[i].Name)
|
Logger.Println(t.Attachments[i].Name)
|
||||||
t.Attachments[i].TemplateId = t.Id
|
t.Attachments[i].TemplateId = t.Id
|
||||||
|
@ -177,6 +185,8 @@ func PutTemplate(t *Template) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save final template
|
||||||
err = db.Where("id=?", t.Id).Save(t).Error
|
err = db.Where("id=?", t.Id).Save(t).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
|
@ -188,11 +198,14 @@ func PutTemplate(t *Template) error {
|
||||||
// DeleteTemplate deletes an existing template in the database.
|
// DeleteTemplate deletes an existing template in the database.
|
||||||
// An error is returned if a template with the given user id and template id is not found.
|
// An error is returned if a template with the given user id and template id is not found.
|
||||||
func DeleteTemplate(id int64, uid int64) error {
|
func DeleteTemplate(id int64, uid int64) error {
|
||||||
|
// Delete attachments
|
||||||
err := db.Where("template_id=?", id).Delete(&Attachment{}).Error
|
err := db.Where("template_id=?", id).Delete(&Attachment{}).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finally, delete the template itself
|
||||||
err = db.Where("user_id=?", uid).Delete(Template{Id: id}).Error
|
err = db.Where("user_id=?", uid).Delete(Template{Id: id}).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -2,6 +2,13 @@ var profiles = []
|
||||||
|
|
||||||
// Attempts to send a test email by POSTing to /campaigns/
|
// Attempts to send a test email by POSTing to /campaigns/
|
||||||
function sendTestEmail() {
|
function sendTestEmail() {
|
||||||
|
var headers = [];
|
||||||
|
$.each($("#headersTable").DataTable().rows().data(), function(i, header) {
|
||||||
|
headers.push({
|
||||||
|
key: unescapeHtml(header[0]),
|
||||||
|
value: unescapeHtml(header[1]),
|
||||||
|
})
|
||||||
|
})
|
||||||
var test_email_request = {
|
var test_email_request = {
|
||||||
template: {},
|
template: {},
|
||||||
first_name: $("input[name=to_first_name]").val(),
|
first_name: $("input[name=to_first_name]").val(),
|
||||||
|
@ -14,7 +21,8 @@ function sendTestEmail() {
|
||||||
host: $("#host").val(),
|
host: $("#host").val(),
|
||||||
username: $("#username").val(),
|
username: $("#username").val(),
|
||||||
password: $("#password").val(),
|
password: $("#password").val(),
|
||||||
ignore_cert_errors: $("#ignore_cert_errors").prop("checked")
|
ignore_cert_errors: $("#ignore_cert_errors").prop("checked"),
|
||||||
|
headers: headers,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
btnHtml = $("#sendTestModalSubmit").html()
|
btnHtml = $("#sendTestModalSubmit").html()
|
||||||
|
@ -35,7 +43,15 @@ function sendTestEmail() {
|
||||||
|
|
||||||
// Save attempts to POST to /smtp/
|
// Save attempts to POST to /smtp/
|
||||||
function save(idx) {
|
function save(idx) {
|
||||||
var profile = {}
|
var profile = {
|
||||||
|
headers: []
|
||||||
|
}
|
||||||
|
$.each($("#headersTable").DataTable().rows().data(), function(i, header) {
|
||||||
|
profile.headers.push({
|
||||||
|
key: unescapeHtml(header[0]),
|
||||||
|
value: unescapeHtml(header[1]),
|
||||||
|
})
|
||||||
|
})
|
||||||
profile.name = $("#name").val()
|
profile.name = $("#name").val()
|
||||||
profile.interface_type = $("#interface_type").val()
|
profile.interface_type = $("#interface_type").val()
|
||||||
profile.from_address = $("#from").val()
|
profile.from_address = $("#from").val()
|
||||||
|
@ -77,6 +93,7 @@ function dismiss() {
|
||||||
$("#username").val("")
|
$("#username").val("")
|
||||||
$("#password").val("")
|
$("#password").val("")
|
||||||
$("#ignore_cert_errors").prop("checked", true)
|
$("#ignore_cert_errors").prop("checked", true)
|
||||||
|
$("#headersTable").dataTable().DataTable().clear().draw()
|
||||||
$("#modal").modal('hide')
|
$("#modal").modal('hide')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +108,14 @@ function deleteProfile(idx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function edit(idx) {
|
function edit(idx) {
|
||||||
|
headers = $("#headersTable").dataTable({
|
||||||
|
destroy: true, // Destroy any other instantiated table - http://datatables.net/manual/tech-notes/3#destroy
|
||||||
|
columnDefs: [{
|
||||||
|
orderable: false,
|
||||||
|
targets: "no-sort"
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
$("#modalSubmit").unbind('click').click(function() {
|
$("#modalSubmit").unbind('click').click(function() {
|
||||||
save(idx)
|
save(idx)
|
||||||
})
|
})
|
||||||
|
@ -104,6 +129,9 @@ function edit(idx) {
|
||||||
$("#username").val(profile.username)
|
$("#username").val(profile.username)
|
||||||
$("#password").val(profile.password)
|
$("#password").val(profile.password)
|
||||||
$("#ignore_cert_errors").prop("checked", profile.ignore_cert_errors)
|
$("#ignore_cert_errors").prop("checked", profile.ignore_cert_errors)
|
||||||
|
$.each(profile.headers, function(i, record) {
|
||||||
|
addCustomHeader(record.key, record.value)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +195,34 @@ function load() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addCustomHeader(header, value) {
|
||||||
|
// Create new data row.
|
||||||
|
var newRow = [
|
||||||
|
escapeHtml(header),
|
||||||
|
escapeHtml(value),
|
||||||
|
'<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Check table to see if header already exists.
|
||||||
|
var headersTable = headers.DataTable();
|
||||||
|
var existingRowIndex = headersTable
|
||||||
|
.column(0) // Email column has index of 2
|
||||||
|
.data()
|
||||||
|
.indexOf(escapeHtml(header));
|
||||||
|
|
||||||
|
// Update or add new row as necessary.
|
||||||
|
if (existingRowIndex >= 0) {
|
||||||
|
headersTable
|
||||||
|
.row(existingRowIndex, {
|
||||||
|
order: "index"
|
||||||
|
})
|
||||||
|
.data(newRow);
|
||||||
|
} else {
|
||||||
|
headersTable.row.add(newRow);
|
||||||
|
}
|
||||||
|
headersTable.draw();
|
||||||
|
}
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
// Setup multiple modals
|
// Setup multiple modals
|
||||||
// Code based on http://miles-by-motorcycle.com/static/bootstrap-modal/index.html
|
// Code based on http://miles-by-motorcycle.com/static/bootstrap-modal/index.html
|
||||||
|
@ -208,5 +264,26 @@ $(document).ready(function() {
|
||||||
$('#modal').on('hidden.bs.modal', function(event) {
|
$('#modal').on('hidden.bs.modal', function(event) {
|
||||||
dismiss()
|
dismiss()
|
||||||
});
|
});
|
||||||
|
// Code to deal with custom email headers
|
||||||
|
$("#headersForm").on('submit', function() {
|
||||||
|
headerKey = $("#headerKey").val();
|
||||||
|
headerValue = $("#headerValue").val();
|
||||||
|
|
||||||
|
if (headerKey == "" || headerValue == "") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
addCustomHeader(headerKey, headerValue);
|
||||||
|
// Reset user input.
|
||||||
|
$("#headersForm>div>input").val('');
|
||||||
|
$("#headerKey").focus();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
// Handle Deletion
|
||||||
|
$("#headersTable").on("click", "span>i.fa-trash-o", function() {
|
||||||
|
headers.DataTable()
|
||||||
|
.row($(this).parents('tr'))
|
||||||
|
.remove()
|
||||||
|
.draw();
|
||||||
|
});
|
||||||
load()
|
load()
|
||||||
})
|
})
|
||||||
|
|
|
@ -42,6 +42,7 @@ function save(idx) {
|
||||||
type: target[4],
|
type: target[4],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
template.id = templates[idx].id
|
template.id = templates[idx].id
|
||||||
api.templateId.put(template)
|
api.templateId.put(template)
|
||||||
|
@ -169,6 +170,7 @@ function edit(idx) {
|
||||||
} else {
|
} else {
|
||||||
$("#use_tracker_checkbox").prop("checked", false)
|
$("#use_tracker_checkbox").prop("checked", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// Handle Deletion
|
// Handle Deletion
|
||||||
$("#attachmentsTable").unbind('click').on("click", "span>i.fa-trash-o", function() {
|
$("#attachmentsTable").unbind('click').on("click", "span>i.fa-trash-o", function() {
|
||||||
|
@ -346,4 +348,5 @@ $(document).ready(function() {
|
||||||
dismiss()
|
dismiss()
|
||||||
});
|
});
|
||||||
load()
|
load()
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -86,8 +86,32 @@
|
||||||
<input id="ignore_cert_errors" type="checkbox" checked>
|
<input id="ignore_cert_errors" type="checkbox" checked>
|
||||||
<label for="ignore_cert_errors">Ignore Certificate Errors <i class="fa fa-question-circle" data-toggle="tooltip" data-placement="right" title="Ignore common certificate errors such as self-signed certs (exposes you to MiTM attacks - use carefully!)"></i></label>
|
<label for="ignore_cert_errors">Ignore Certificate Errors <i class="fa fa-question-circle" data-toggle="tooltip" data-placement="right" title="Ignore common certificate errors such as self-signed certs (exposes you to MiTM attacks - use carefully!)"></i></label>
|
||||||
</div>
|
</div>
|
||||||
|
<label class="control-label" for="headersForm">Email Headers:</label>
|
||||||
|
<form id="headersForm">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<input type="text" class="form-control" name="headerKey" id="headerKey" placeholder="X-Custom-Header">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<input type="text" class="form-control" name="headerValue" id="headerValue" placeholder="{{"{{"}}.URL{{"}}"}}-gophish">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<button class="btn btn-danger btn-headers" type="submit"><i class="fa fa-plus"></i> Add Custom Header</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<table id="headersTable" class="table table-hover table-striped table-condensed">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Header</th>
|
||||||
|
<th>Value</th>
|
||||||
|
<th class="no-sort"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
<button type="button" data-toggle="modal" data-target="#sendTestEmailModal" class="btn btn-primary"><i class="fa fa-envelope"></i> Send Test Email</button>
|
<button type="button" data-toggle="modal" data-target="#sendTestEmailModal" class="btn btn-primary"><i class="fa fa-envelope"></i> Send Test Email</button>
|
||||||
<!-- disable sendTestEmail functionality on sending profile page until update handling of /util/send_test_email -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
@ -136,7 +160,5 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{define "scripts"}}
|
{{define "scripts"}}
|
||||||
<script src="/js/ckeditor/ckeditor.js"></script>
|
|
||||||
<script src="/js/ckeditor/adapters/jquery.js"></script>
|
|
||||||
<script src="/js/dist/app/sending_profiles.min.js"></script>
|
<script src="/js/dist/app/sending_profiles.min.js"></script>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -117,6 +117,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<hr>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" data-dismiss="modal" class="btn btn-default" onclick="dismiss()">Cancel</button>
|
<button type="button" data-dismiss="modal" class="btn btn-default" onclick="dismiss()">Cancel</button>
|
||||||
|
|
|
@ -127,7 +127,36 @@ func processCampaign(c *models.Campaign) {
|
||||||
"<img alt='' style='display: none' src='" + c.URL + "/track?rid=" + t.RId + "'/>",
|
"<img alt='' style='display: none' src='" + c.URL + "/track?rid=" + t.RId + "'/>",
|
||||||
fn,
|
fn,
|
||||||
}
|
}
|
||||||
// Parse the templates
|
|
||||||
|
// Parse the customHeader templates
|
||||||
|
for _, header := range c.SMTP.Headers {
|
||||||
|
parsedHeader := struct {
|
||||||
|
Key bytes.Buffer
|
||||||
|
Value bytes.Buffer
|
||||||
|
}{}
|
||||||
|
keytmpl, err := template.New("text_template").Parse(header.Key)
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
}
|
||||||
|
err = keytmpl.Execute(&parsedHeader.Key, td)
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
valtmpl, err := template.New("text_template").Parse(header.Value)
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
}
|
||||||
|
err = valtmpl.Execute(&parsedHeader.Value, td)
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add our header immediately
|
||||||
|
e.SetHeader(parsedHeader.Key.String(), parsedHeader.Value.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse remaining templates
|
||||||
var subjBuff bytes.Buffer
|
var subjBuff bytes.Buffer
|
||||||
tmpl, err := template.New("text_template").Parse(c.Template.Subject)
|
tmpl, err := template.New("text_template").Parse(c.Template.Subject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -243,10 +272,37 @@ func SendTestEmail(s *models.SendTestEmailRequest) error {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Logger.Println("Creating email using template")
|
||||||
e := gomail.NewMessage()
|
e := gomail.NewMessage()
|
||||||
|
// Parse the customHeader templates
|
||||||
|
for _, header := range s.SMTP.Headers {
|
||||||
|
parsedHeader := struct {
|
||||||
|
Key bytes.Buffer
|
||||||
|
Value bytes.Buffer
|
||||||
|
}{}
|
||||||
|
keytmpl, err := template.New("text_template").Parse(header.Key)
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
}
|
||||||
|
err = keytmpl.Execute(&parsedHeader.Key, s)
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
valtmpl, err := template.New("text_template").Parse(header.Value)
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
}
|
||||||
|
err = valtmpl.Execute(&parsedHeader.Value, s)
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add our header immediately
|
||||||
|
e.SetHeader(parsedHeader.Key.String(), parsedHeader.Value.String())
|
||||||
|
}
|
||||||
e.SetHeader("From", s.SMTP.FromAddress)
|
e.SetHeader("From", s.SMTP.FromAddress)
|
||||||
e.SetHeader("To", s.Email)
|
e.SetHeader("To", s.Email)
|
||||||
Logger.Println("Creating email using template")
|
|
||||||
// Parse the templates
|
// Parse the templates
|
||||||
var subjBuff bytes.Buffer
|
var subjBuff bytes.Buffer
|
||||||
tmpl, err := template.New("text_template").Parse(s.Template.Subject)
|
tmpl, err := template.New("text_template").Parse(s.Template.Subject)
|
||||||
|
|
Loading…
Reference in New Issue