Fix leak of first recipient to other recipients because mail headers are also cached and re-used

This commit is contained in:
ChaoticByte 2025-06-16 17:29:38 +02:00
parent a4fd43e03d
commit c1b3d106a0
No known key found for this signature in database
4 changed files with 23 additions and 17 deletions

View file

@ -47,30 +47,30 @@ type SmtpSettings struct {
Password string `json:"password"` Password string `json:"password"`
} }
func sendNotices(recipient string, notices []*WidNotice, template MailTemplate, auth smtp.Auth, smtpConfig SmtpSettings, cache *map[string][]byte) error { func sendNotices(recipient string, notices []*WidNotice, template MailTemplate, auth smtp.Auth, smtpConfig SmtpSettings, mailContentCache *map[string]*MailContent) error {
logger.debug("Generating and sending mails for recipient " + recipient + " ...") logger.debug("Generating and sending mails for recipient " + recipient + " ...")
cacheHits := 0 cacheHits := 0
cacheMisses := 0 cacheMisses := 0
mails := [][]byte{} mails := []*MailContent{}
for _, n := range notices { for _, n := range notices {
var data []byte var mc *MailContent
cacheResult := (*cache)[n.Uuid] cacheResult := (*mailContentCache)[n.Uuid]
if len(cacheResult) > 0 { if cacheResult != nil {
cacheHits++ cacheHits++
data = cacheResult mc = cacheResult
} else { } else {
cacheMisses++ cacheMisses++
mailContent, err := template.generate(TemplateData{n, Version}) mc_, err := template.generate(TemplateData{n, Version})
if err != nil { if err != nil {
logger.error("Could not create mail from template") logger.error("Could not create mail from template")
logger.error(err) logger.error(err)
} else {
mc = &mc_
// add to cache
(*mailContentCache)[n.Uuid] = mc
} }
// serialize mail
data = mailContent.serializeValidMail(smtpConfig.From, recipient)
// add to cache
(*cache)[n.Uuid] = data
} }
mails = append(mails, data) mails = append(mails, mc)
} }
logger.debug(fmt.Sprintf("%v mail cache hits, %v misses", cacheHits, cacheMisses)) logger.debug(fmt.Sprintf("%v mail cache hits, %v misses", cacheHits, cacheMisses))
err := sendMails( err := sendMails(

View file

@ -11,7 +11,7 @@ import (
) )
func sendMails(smtpConf SmtpSettings, auth smtp.Auth, to string, data [][]byte) error { func sendMails(smtpConf SmtpSettings, auth smtp.Auth, to string, mails []*MailContent) error {
addr := fmt.Sprintf("%v:%v", smtpConf.ServerHost, smtpConf.ServerPort) addr := fmt.Sprintf("%v:%v", smtpConf.ServerHost, smtpConf.ServerPort)
logger.debug("Connecting to mail server at " + addr + " ...") logger.debug("Connecting to mail server at " + addr + " ...")
connection, err := smtp.Dial(addr) connection, err := smtp.Dial(addr)
@ -32,7 +32,10 @@ func sendMails(smtpConf SmtpSettings, auth smtp.Auth, to string, data [][]byte)
if logger.LogLevel >= 3 { if logger.LogLevel >= 3 {
fmt.Printf("DEBUG %v Sending mails to server ", time.Now().Format("2006/01/02 15:04:05.000000")) fmt.Printf("DEBUG %v Sending mails to server ", time.Now().Format("2006/01/02 15:04:05.000000"))
} }
for _, d := range data { for _, mc := range mails {
// serialize mail
d := mc.serializeValidMail(smtpConf.From, to)
// send mail
err = connection.Mail(smtpConf.From) err = connection.Mail(smtpConf.From)
if err != nil { return err } if err != nil { return err }
err = connection.Rcpt(to) err = connection.Rcpt(to)

View file

@ -8,10 +8,13 @@ import (
"net/smtp" "net/smtp"
) )
func sendMails(smtpConf SmtpSettings, auth smtp.Auth, to string, data [][]byte) error { func sendMails(smtpConf SmtpSettings, auth smtp.Auth, to string, mails []*MailContent) error {
logger.warn("Mail Transfer Debugging is active. Not connecting.") logger.warn("Mail Transfer Debugging is active. Not connecting.")
logger.info("MAIL TRANSFER: \n\n") logger.info("MAIL TRANSFER: \n\n")
for _, d := range data { for _, mc := range mails {
// serialize mail
d := mc.serializeValidMail(smtpConf.From, to)
// output mail
fmt.Println("MAIL FROM:" + smtpConf.From) fmt.Println("MAIL FROM:" + smtpConf.From)
fmt.Println("RCPT TO:" + to) fmt.Println("RCPT TO:" + to)
fmt.Println("DATA") fmt.Println("DATA")

View file

@ -98,7 +98,7 @@ func main() {
t1 := time.Now().UnixMilli() t1 := time.Now().UnixMilli()
newNotices := []WidNotice{} newNotices := []WidNotice{}
lastPublished := map[string]time.Time{} // endpoint id : last published timestamp lastPublished := map[string]time.Time{} // endpoint id : last published timestamp
cache := map[string][]byte{} // cache generated emails for reuse cache := map[string]*MailContent{} // cache generated emails for reuse
for _, a := range enabledApiEndpoints { for _, a := range enabledApiEndpoints {
logger.info("Querying endpoint '" + a.Id + "' for new notices ...") logger.info("Querying endpoint '" + a.Id + "' for new notices ...")
n, t, err := a.getNotices(persistent.data.(PersistentData).LastPublished[a.Id]) n, t, err := a.getNotices(persistent.data.(PersistentData).LastPublished[a.Id])