mox/message/from.go
Mechiel Lukkien 34c2dcd49d
add strict mode when parsing messages, typically enabled for incoming special-use messages like tls/dmarc reports, subjectpass emails
and pass a logger to the message parser, so problems with message parsing get
the cid logged.
2023-08-15 08:25:56 +02:00

44 lines
1.4 KiB
Go

package message
import (
"fmt"
"io"
"net/textproto"
"github.com/mjl-/mox/dns"
"github.com/mjl-/mox/mlog"
"github.com/mjl-/mox/smtp"
)
// From extracts the address in the From-header.
//
// An RFC5322 message must have a From header.
// In theory, multiple addresses may be present. In practice zero or multiple
// From headers may be present. From returns an error if there is not exactly
// one address. This address can be used for evaluating a DMARC policy against
// SPF and DKIM results.
func From(log *mlog.Log, strict bool, r io.ReaderAt) (raddr smtp.Address, header textproto.MIMEHeader, rerr error) {
// ../rfc/7489:1243
// todo: only allow utf8 if enabled in session/message?
p, err := Parse(log, strict, r)
if err != nil {
// todo: should we continue with p, perhaps headers can be parsed?
return raddr, nil, fmt.Errorf("parsing message: %v", err)
}
header, err = p.Header()
if err != nil {
return raddr, nil, fmt.Errorf("parsing message header: %v", err)
}
from := p.Envelope.From
if len(from) != 1 {
return raddr, nil, fmt.Errorf("from header has %d addresses, need exactly 1 address", len(from))
}
d, err := dns.ParseDomain(from[0].Host)
if err != nil {
return raddr, nil, fmt.Errorf("bad domain in from address: %v", err)
}
addr := smtp.Address{Localpart: smtp.Localpart(from[0].User), Domain: d}
return addr, textproto.MIMEHeader(header), nil
}