51 lines
1.2 KiB
Go
51 lines
1.2 KiB
Go
package mailparser
|
|
|
|
import (
|
|
"net/mail"
|
|
"strings"
|
|
)
|
|
|
|
var deliveryHeaders = []string{"Delivered-To", "X-Original-To", "Envelope-To"}
|
|
|
|
// Only the topmost occurrence per header counts: it is the one our own
|
|
// mailserver added last; lower ones stem from forwarding hops or the sender.
|
|
func deliveryAddresses(h mail.Header) []string {
|
|
var out []string
|
|
seen := make(map[string]struct{})
|
|
for _, name := range deliveryHeaders {
|
|
values := h[name]
|
|
if len(values) == 0 {
|
|
continue
|
|
}
|
|
addrs, err := mail.ParseAddressList(values[0])
|
|
if err != nil {
|
|
continue
|
|
}
|
|
for _, a := range addrs {
|
|
addr := strings.ToLower(strings.TrimSpace(a.Address))
|
|
if addr == "" {
|
|
continue
|
|
}
|
|
if _, dup := seen[addr]; dup {
|
|
continue
|
|
}
|
|
seen[addr] = struct{}{}
|
|
out = append(out, addr)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
// Delivery headers are only set by our own mailserver for pull sources; for
|
|
// SMTP intake and uploads/imports they are sender-controlled.
|
|
func IsTrustedDeliverySource(sourceType string) bool {
|
|
return sourceType == "imap" || sourceType == "pop3"
|
|
}
|
|
|
|
func TrustedDeliveryAddresses(pm *ParsedMail, sourceType string) []string {
|
|
if pm == nil || !IsTrustedDeliverySource(sourceType) {
|
|
return nil
|
|
}
|
|
return pm.DeliveryAddresses
|
|
}
|