1package smtpserver
2
3import (
4 "context"
5 "fmt"
6
7 "github.com/mjl-/mox/dsn"
8 "github.com/mjl-/mox/queue"
9 "github.com/mjl-/mox/smtp"
10 "github.com/mjl-/mox/store"
11)
12
13// compose dsn message and add it to the queue for delivery to rcptTo.
14func queueDSN(ctx context.Context, c *conn, rcptTo smtp.Path, m dsn.Message, requireTLS bool) error {
15 buf, err := m.Compose(c.log, false)
16 if err != nil {
17 return err
18 }
19 var bufUTF8 []byte
20 if c.smtputf8 {
21 bufUTF8, err = m.Compose(c.log, true)
22 if err != nil {
23 c.log.Errorx("composing dsn with utf-8 for incoming delivery for unknown user, continuing with ascii-only dsn", err)
24 }
25 }
26
27 f, err := store.CreateMessageTemp("smtp-dsn")
28 if err != nil {
29 return fmt.Errorf("creating temp file: %w", err)
30 }
31 defer store.CloseRemoveTempFile(c.log, f, "smtpserver dsn message")
32
33 if _, err := f.Write([]byte(buf)); err != nil {
34 return fmt.Errorf("writing dsn file: %w", err)
35 }
36
37 // Queue DSN with null reverse path so failures to deliver will eventually drop the
38 // message instead of causing delivery loops.
39 // ../rfc/3464:433
40 const has8bit = false
41 const smtputf8 = false
42 var reqTLS *bool
43 if requireTLS {
44 reqTLS = &requireTLS
45 }
46 qm := queue.MakeMsg("", smtp.Path{}, rcptTo, has8bit, smtputf8, int64(len(buf)), m.MessageID, nil, reqTLS)
47 qm.DSNUTF8 = bufUTF8
48 if err := queue.Add(ctx, c.log, &qm, f); err != nil {
49 return err
50 }
51 return nil
52}
53