mox/smtpserver/dsn.go
Mechiel Lukkien 72ac1fde29
expose fewer internals in packages, for easier software reuse
- prometheus is now behind an interface, they aren't dependencies for the
  reusable components anymore.
- some dependencies have been inverted: instead of packages importing a main
  package to get configuration, the main package now sets configuration in
  these packages. that means fewer internals are pulled in.
- some functions now have new parameters for values that were retrieved from
  package "mox-".
2023-12-14 15:39:36 +01:00

62 lines
1.7 KiB
Go

package smtpserver
import (
"context"
"fmt"
"github.com/mjl-/mox/dsn"
"github.com/mjl-/mox/mlog"
"github.com/mjl-/mox/mox-"
"github.com/mjl-/mox/queue"
"github.com/mjl-/mox/smtp"
"github.com/mjl-/mox/store"
)
// compose dsn message and add it to the queue for delivery to rcptTo.
func queueDSN(ctx context.Context, log mlog.Log, c *conn, rcptTo smtp.Path, m dsn.Message, requireTLS bool) error {
buf, err := m.Compose(c.log, false)
if err != nil {
return err
}
bufDKIM, err := mox.DKIMSign(ctx, c.log, m.From, false, buf)
log.Check(err, "dkim signing dsn")
buf = append([]byte(bufDKIM), buf...)
var bufUTF8 []byte
if c.smtputf8 {
bufUTF8, err = m.Compose(c.log, true)
if err != nil {
c.log.Errorx("composing dsn with utf-8 for incoming delivery for unknown user, continuing with ascii-only dsn", err)
} else {
bufUTF8DKIM, err := mox.DKIMSign(ctx, log, m.From, true, bufUTF8)
log.Check(err, "dkim signing dsn with utf8")
bufUTF8 = append([]byte(bufUTF8DKIM), bufUTF8...)
}
}
f, err := store.CreateMessageTemp(c.log, "smtp-dsn")
if err != nil {
return fmt.Errorf("creating temp file: %w", err)
}
defer store.CloseRemoveTempFile(c.log, f, "smtpserver dsn message")
if _, err := f.Write([]byte(buf)); err != nil {
return fmt.Errorf("writing dsn file: %w", err)
}
// Queue DSN with null reverse path so failures to deliver will eventually drop the
// message instead of causing delivery loops.
// ../rfc/3464:433
const has8bit = false
const smtputf8 = false
var reqTLS *bool
if requireTLS {
reqTLS = &requireTLS
}
qm := queue.MakeMsg("", smtp.Path{}, rcptTo, has8bit, smtputf8, int64(len(buf)), m.MessageID, nil, reqTLS)
qm.DSNUTF8 = bufUTF8
if err := queue.Add(ctx, c.log, &qm, f); err != nil {
return err
}
return nil
}