new: if no smtp configuration is found arc will use the local sendmail binary (fixes #129)

This commit is contained in:
Simone Margaritelli
2021-01-09 19:45:30 +01:00
parent ddcdc13039
commit eecb586dac
4 changed files with 89 additions and 35 deletions

View File

@@ -132,7 +132,7 @@ It is necessary to change only the `username` and `password` access parameters o
| scheduler.reports.rate\_limit | If two events of the same type are triggered in less than this number of seconds between one each other, the newest will not be notified by email. |
| scheduler.reports.filter | Which type of events to report by email. |
| scheduler.reports.to | Destination email address. |
| scheduler.reports.smtp | SMTP server information. |
| scheduler.reports.smtp | SMTP server information, if not provided the local sendmail binary will be used. |
| scheduler.reports.pgp.enabled | If true, email notifications will be encrypted with PGP. |
| scheduler.reports.pgp.keys.private | Path of the private key file to use to encrypt emails, if not found or empty it will be automatically generated by `arc`. |
| scheduler.reports.pgp.keys.public | Path of the PGP public key of the email notifications recipient. |

View File

@@ -42,6 +42,10 @@ type SMTPConfig struct {
Password string `json:"password"`
}
func (c SMTPConfig) Filled() bool {
return c.Address != ""
}
type KeyPair struct {
Public string `json:"public"`
Private string `json:"private"`

81
events/mail.go Normal file
View File

@@ -0,0 +1,81 @@
package events
import (
"bytes"
"crypto/tls"
"fmt"
"github.com/evilsocket/arc/config"
"github.com/evilsocket/arc/pgp"
"github.com/evilsocket/islazy/log"
"gopkg.in/gomail.v2"
"os"
"os/exec"
)
func doEmailReport(event Event) (err error) {
smtp := config.Conf.Scheduler.Reports.SMTP
contentType := "text/html"
reportType := "plaintext"
if pgpConf.Enabled {
reportType = "PGP encrypted"
}
body := event.Description
if pgpConf.Enabled {
contentType = "text/plain"
if err, body = pgp.Encrypt(body); err != nil {
return fmt.Errorf("could not PGP encrypt the message: %v", err)
}
}
log.Info("reporting %s event '%s' to %s ...",
reportType,
event.Title,
config.Conf.Scheduler.Reports.To)
if smtp.Filled() {
log.Info("using smtp server")
d := gomail.NewDialer(smtp.Address, smtp.Port, smtp.Username, smtp.Password)
d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
m := gomail.NewMessage()
m.SetHeader("From", fmt.Sprintf("Arc Reporting System <%s>", smtp.Username))
m.SetHeader("To", config.Conf.Scheduler.Reports.To)
m.SetHeader("Subject", event.Title)
m.SetBody(contentType, body)
if err := d.DialAndSend(m); err != nil {
return err
}
} else if sendmailPath, err := exec.LookPath("sendmail"); err != nil {
return fmt.Errorf("error searching sendmail binary: %v", err)
} else {
log.Info("using %s", sendmailPath)
cmd := exec.Command(sendmailPath, "-t")
body = "From: arc@localhost\n" +
fmt.Sprintf("To: %s", config.Conf.Scheduler.Reports.To ) + "\n" +
fmt.Sprintf("Subject: %s", event.Title ) + "\n" +
fmt.Sprintf("Content-Type: %s", contentType ) + "\n" +
"Content-Transfer-Encoding: 7BIT\n" +
"Content-Disposition: inline\n" +
"MIME-Version: 1.0\n" +
"\n" +
body
buffer := bytes.Buffer{}
buffer.Write([]byte(body))
cmd.Stdin = &buffer
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
return nil
}

View File

@@ -8,13 +8,10 @@
package events
import (
"crypto/tls"
"fmt"
"github.com/evilsocket/arc/config"
"github.com/evilsocket/islazy/log"
"github.com/evilsocket/arc/pgp"
"github.com/evilsocket/arc/utils"
"gopkg.in/gomail.v2"
"github.com/evilsocket/islazy/log"
"sync"
"time"
)
@@ -62,36 +59,8 @@ func Report(event Event) {
return
}
repotype := "plaintext"
if pgpConf.Enabled {
repotype = "PGP encrypted"
}
log.Info("Reporting %s event '%s' to %s ...", repotype, event.Title, config.Conf.Scheduler.Reports.To)
smtp := config.Conf.Scheduler.Reports.SMTP
d := gomail.NewDialer(smtp.Address, smtp.Port, smtp.Username, smtp.Password)
d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
m := gomail.NewMessage()
m.SetHeader("From", fmt.Sprintf("Arc Reporting System <%s>", smtp.Username))
m.SetHeader("To", config.Conf.Scheduler.Reports.To)
m.SetHeader("Subject", event.Title)
var err error
ctype := "text/html"
body := event.Description
if pgpConf.Enabled {
ctype = "text/plain"
if err, body = pgp.Encrypt(body); err != nil {
log.Error("Could not PGP encrypt the message: %s.", err)
}
}
m.SetBody(ctype, body)
if err := d.DialAndSend(m); err != nil {
log.Error("Error: %s.", err)
if err := doEmailReport(event); err != nil {
log.Error("%v", err)
}
}