maddy/module/msgmetadata.go
fox.cpp 3270ba57ba
Perform rDNS lookup asynchronously and generate Received early
New implementation newer inserts 'for' field into Received field.
It could reveal details of address aliases and forwarding used by
server, we don't want to make this possible.

Closes #135.
2019-09-18 22:59:31 +03:00

117 lines
4 KiB
Go

package module
import (
"crypto/tls"
"net"
"github.com/foxcpp/maddy/future"
)
// MsgMetadata structure contains all information about the origin of
// the message and all associated flags indicating how it should be handled
// by components.
//
// All fields should be considered read-only except when otherwise is noted.
// Module instances should avoid keeping reference to the instance passed
// to it since flags may be changed and copy the structure using DeepCopy
// method instead.
type MsgMetadata struct {
// Unique identifier for this message. Randomly generated by the
// message source module.
ID string
// Original message sender address as it was received by the message source.
//
// Note that this field is meant for use for tracing purposes.
// All routing and other decisions should be made based on the sender address
// passed separately (for example, mailFrom argument for CheckSender function)
// Note that addresses may contain unescaped Unicode characters.
OriginalFrom string
// Set to true if message is received over SMTP and client is authenticated
// anonymously.
Anonymous bool
// If message is received over SMTP and client is authenticated
// non-anonymously - this field contains used username.
AuthUser string
// If message is received over SMTP and client is authenticated
// non-anonymously - this field contains used password.
AuthPassword string
// IANA protocol name (SMTP, ESMTP, ESMTPS, etc)
//
// If message was generated internally - this field will be empty.
SrcProto string
// If message is received over SMTPS - TLS connection state.
SrcTLSState tls.ConnectionState
// If message is received over SMTP - this field contains
// the hostname sent by client in EHLO/HELO command.
//
// If message was generated internally - this field will be
// be equal to the local hostname.
SrcHostname string
// If message is received over SMTP - this field contains
// network address of client.
//
// If message was generated internally - this field will be
// nil.
SrcAddr net.Addr
// SrcRDNSName is contains the result of Reverse DNS lookup
// performed on SrcAddr value.
//
// Future underlying type is string or untyped nil value.
// It's message source responsibility to populate
// this field.
//
// Valid states of this field consumers need to be aware of:
// SrcRDNSName = nil
// Reverse DNS lookup is not applicable for that
// message source. Typically the case for messages
// auto-generated internally.
// SrcRDNSName != nil, but Get returns nil
// Reverse DNS lookup was attempted, but resulted in
// error. Consumers should assume that the PTR record
// doesn't exist.
SrcRDNSName *future.Future
// If set - no SrcHostname and SrcAddr will be added to Received
// header. These fields are still written to the server log.
DontTraceSender bool
// Size of message body. It is updated by pipeline code after each step
// that changes body.
BodyLength int
// Quarantine is a message flag that is should be set if message is
// considered "suspicious" and should be put into "Junk" folder
// in the storage.
//
// This field should not be modified by the checks that verify
// the message. It is set only by the message dispatcher.
Quarantine bool
// OriginalRcpts contains the mapping from the final recipient to the
// recipient that was presented by the client.
//
// Modules that rewrite recipients should update this mapping (and
// initialize it, if needed).
//
// It should be used when reporting information back to client (via DSN,
// for example) to prevent disclosing information about aliases
// which is usually unwanted.
OriginalRcpts map[string]string
}
// DeepCopy creates a copy of the MsgMetadata structure, also
// copying contents of the maps and slices.
//
// There are a few exceptions, however:
// - SrcAddr is not copied and copy field references original value.
func (msgMeta *MsgMetadata) DeepCopy() *MsgMetadata {
cpy := *msgMeta
// There is no good way to copy net.Addr, but it should not be
// modified by anything anyway so we are safe.
return &cpy
}