package milter
import "github.com/emersion/go-milter"
Package milter provides an interface to implement milter mail filters
Index ¶
- Constants
- Variables
- type Action
- type ActionCode
- type Client
- func NewClientWithOptions(network, address string, opts ClientOptions) *Client
- func NewDefaultClient(network, address string) *Client
- func (c *Client) Close() error
- func (c *Client) Session() (*ClientSession, error)
- type ClientOptions
- type ClientSession
- func (s *ClientSession) Abort() error
- func (s *ClientSession) ActionOption(opt OptAction) bool
- func (s *ClientSession) BodyChunk(chunk []byte) (*Action, error)
- func (s *ClientSession) BodyReadFrom(r io.Reader) ([]ModifyAction, *Action, error)
- func (s *ClientSession) Close() error
- func (s *ClientSession) Conn(hostname string, family ProtoFamily, port uint16, addr string) (*Action, error)
- func (s *ClientSession) End() ([]ModifyAction, *Action, error)
- func (s *ClientSession) Header(hdr textproto.Header) (*Action, error)
- func (s *ClientSession) HeaderEnd() (*Action, error)
- func (s *ClientSession) HeaderField(key, value string) (*Action, error)
- func (s *ClientSession) Helo(helo string) (*Action, error)
- func (s *ClientSession) Macros(code Code, kv ...string) error
- func (s *ClientSession) Mail(sender string, esmtpArgs []string) (*Action, error)
- func (s *ClientSession) ProtocolOption(opt OptProtocol) bool
- func (s *ClientSession) Rcpt(rcpt string, esmtpArgs []string) (*Action, error)
- type Code
- type CustomResponse
- func NewResponse(code byte, data []byte) *CustomResponse
- func NewResponseStr(code byte, data string) *CustomResponse
- func (c *CustomResponse) Continue() bool
- func (c *CustomResponse) Response() *Message
- type Dialer
- type Message
- type Milter
- type Modifier
- func (m *Modifier) AddHeader(name, value string) error
- func (m *Modifier) AddRecipient(r string) error
- func (m *Modifier) ChangeFrom(value string) error
- func (m *Modifier) ChangeHeader(index int, name, value string) error
- func (m *Modifier) DeleteRecipient(r string) error
- func (m *Modifier) InsertHeader(index int, name, value string) error
- func (m *Modifier) Quarantine(reason string) error
- func (m *Modifier) ReplaceBody(body []byte) error
- type ModifyActCode
- type ModifyAction
- type NoOpMilter
- func (NoOpMilter) Abort(m *Modifier) error
- func (NoOpMilter) Body(m *Modifier) (Response, error)
- func (NoOpMilter) BodyChunk(chunk []byte, m *Modifier) (Response, error)
- func (NoOpMilter) Connect(host string, family string, port uint16, addr net.IP, m *Modifier) (Response, error)
- func (NoOpMilter) Header(name string, value string, m *Modifier) (Response, error)
- func (NoOpMilter) Headers(h textproto.MIMEHeader, m *Modifier) (Response, error)
- func (NoOpMilter) Helo(name string, m *Modifier) (Response, error)
- func (NoOpMilter) MailFrom(from string, m *Modifier) (Response, error)
- func (NoOpMilter) RcptTo(rcptTo string, m *Modifier) (Response, error)
- type OptAction
- type OptProtocol
- type ProtoFamily
- type Response
- type Server
- type SimpleResponse
Constants ¶
const ( RespAccept = SimpleResponse(ActAccept) RespContinue = SimpleResponse(ActContinue) RespDiscard = SimpleResponse(ActDiscard) RespReject = SimpleResponse(ActReject) RespTempFail = SimpleResponse(ActTempFail) )
Define standard responses with no data
const MaxBodyChunk = 65535
Variables ¶
ErrServerClosed is returned by the Server's Serve method after a call to Close.
Types ¶
type Action ¶
type Action struct { Code ActionCode // SMTP code if Code == ActReplyCode. SMTPCode int // Reply text if Code == ActReplyCode. SMTPText string }
type ActionCode ¶
type ActionCode byte
const ( ActAccept ActionCode = 'a' // SMFIR_ACCEPT ActContinue ActionCode = 'c' // SMFIR_CONTINUE ActDiscard ActionCode = 'd' // SMFIR_DISCARD ActReject ActionCode = 'r' // SMFIR_REJECT ActTempFail ActionCode = 't' // SMFIR_TEMPFAIL ActReplyCode ActionCode = 'y' // SMFIR_REPLYCODE // [v6] ActSkip ActionCode = 's' // SMFIR_SKIP )
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a wrapper for managing milter connections.
Currently, it just creates new connections using provided Dialer.
func NewClientWithOptions ¶
func NewClientWithOptions(network, address string, opts ClientOptions) *Client
NewClientWithOptions creates a new Client object using provided options.
You generally want to use options to restrict ActionMask to what your code supports and ProtocolMask to what you intend to submit.
If opts.Dialer is not set, empty net.Dialer object will be used.
func NewDefaultClient ¶
NewDefaultClient creates a new Client object using default options.
It uses 10 seconds for connection/read/write timeouts and allows milter to send any actions supported by library.
func (*Client) Close ¶
func (*Client) Session ¶
func (c *Client) Session() (*ClientSession, error)
type ClientOptions ¶
type ClientOptions struct { Dialer Dialer ReadTimeout time.Duration WriteTimeout time.Duration ActionMask OptAction ProtocolMask OptProtocol }
type ClientSession ¶
type ClientSession struct { // Bitmask of negotiated action options. ActionOpts OptAction // Bitmask of negotiated protocol options. ProtocolOpts OptProtocol // contains filtered or unexported fields }
func (*ClientSession) Abort ¶
func (s *ClientSession) Abort() error
Abort sends Abort to the milter.
This is called for an unexpected end to an email outside the milters control.
func (*ClientSession) ActionOption ¶
func (s *ClientSession) ActionOption(opt OptAction) bool
ActionOption checks whether the option is set in negotiated options, that is, requested by both sides.
func (*ClientSession) BodyChunk ¶
func (s *ClientSession) BodyChunk(chunk []byte) (*Action, error)
BodyChunk sends a single body chunk to the milter.
It is callers responsibility to ensure every chunk is not bigger than MaxBodyChunk.
If OptSkip was specified during negotiation, caller should be ready to handle return ActSkip and stop sending body chunks if it is returned.
func (*ClientSession) BodyReadFrom ¶
func (s *ClientSession) BodyReadFrom(r io.Reader) ([]ModifyAction, *Action, error)
BodyReadFrom is a helper function that calls BodyChunk repeately to transmit entire body from io.Reader and then calls End.
See documentation for these functions for details.
func (*ClientSession) Close ¶
func (s *ClientSession) Close() error
Close releases resources associated with the session.
If there a milter sequence in progress - it is aborted.
func (*ClientSession) Conn ¶
func (s *ClientSession) Conn(hostname string, family ProtoFamily, port uint16, addr string) (*Action, error)
Conn sends the connection information to the milter.
It should be called once per milter session (from Session to Close).
func (*ClientSession) End ¶
func (s *ClientSession) End() ([]ModifyAction, *Action, error)
End sends the EOB message and resets session back to the state before Mail call. The same ClientSession can be used to check another message arrived within the same SMTP connection (Helo and Conn information is preserved).
Close should be called to conclude session.
func (*ClientSession) Header ¶
func (s *ClientSession) Header(hdr textproto.Header) (*Action, error)
Header sends each field from textproto.Header followed by EOH unless header messages are disabled during negotiation.
func (*ClientSession) HeaderEnd ¶
func (s *ClientSession) HeaderEnd() (*Action, error)
HeaderEnd send the EOH (End-Of-Header) message to the milter.
No HeaderField calls are allowed after this point.
func (*ClientSession) HeaderField ¶
func (s *ClientSession) HeaderField(key, value string) (*Action, error)
HeaderField sends a single header field to the milter.
Value should be the original field value without any unfolding applied.
HeaderEnd() must be called after the last field.
func (*ClientSession) Helo ¶
func (s *ClientSession) Helo(helo string) (*Action, error)
Helo sends the HELO hostname to the milter.
It should be called once per milter session (from Session to Close).
func (*ClientSession) Macros ¶
func (s *ClientSession) Macros(code Code, kv ...string) error
func (*ClientSession) Mail ¶
func (s *ClientSession) Mail(sender string, esmtpArgs []string) (*Action, error)
func (*ClientSession) ProtocolOption ¶
func (s *ClientSession) ProtocolOption(opt OptProtocol) bool
ProtocolOption checks whether the option is set in negotiated options, that is, requested by both sides.
func (*ClientSession) Rcpt ¶
func (s *ClientSession) Rcpt(rcpt string, esmtpArgs []string) (*Action, error)
type Code ¶
type Code byte
const ( CodeOptNeg Code = 'O' // SMFIC_OPTNEG CodeMacro Code = 'D' // SMFIC_MACRO CodeConn Code = 'C' // SMFIC_CONNECT CodeQuit Code = 'Q' // SMFIC_QUIT CodeHelo Code = 'H' // SMFIC_HELO CodeMail Code = 'M' // SMFIC_MAIL CodeRcpt Code = 'R' // SMFIC_RCPT CodeHeader Code = 'L' // SMFIC_HEADER CodeEOH Code = 'N' // SMFIC_EOH CodeBody Code = 'B' // SMFIC_BODY CodeEOB Code = 'E' // SMFIC_BODYEOB CodeAbort Code = 'A' // SMFIC_ABORT CodeData Code = 'T' // SMFIC_DATA // [v6] CodeQuitNewConn Code = 'K' // SMFIC_QUIT_NC )
type CustomResponse ¶
type CustomResponse struct {
// contains filtered or unexported fields
}
CustomResponse is a response instance used by callback handlers to indicate how the milter should continue processing of current message
func NewResponse ¶
func NewResponse(code byte, data []byte) *CustomResponse
NewResponse generates a new CustomResponse suitable for WritePacket
func NewResponseStr ¶
func NewResponseStr(code byte, data string) *CustomResponse
NewResponseStr generates a new CustomResponse with string payload
func (*CustomResponse) Continue ¶
func (c *CustomResponse) Continue() bool
Continue returns false if milter chain should be stopped, true otherwise
func (*CustomResponse) Response ¶
func (c *CustomResponse) Response() *Message
Response returns message instance with data
type Dialer ¶
type Message ¶
Message represents a command sent from milter client
type Milter ¶
type Milter interface { // Connect is called to provide SMTP connection data for incoming message. // Suppress with OptNoConnect. Connect(host string, family string, port uint16, addr net.IP, m *Modifier) (Response, error) // Helo is called to process any HELO/EHLO related filters. Suppress with // OptNoHelo. Helo(name string, m *Modifier) (Response, error) // MailFrom is called to process filters on envelope FROM address. Suppress // with OptNoMailFrom. MailFrom(from string, m *Modifier) (Response, error) // RcptTo is called to process filters on envelope TO address. Suppress with // OptNoRcptTo. RcptTo(rcptTo string, m *Modifier) (Response, error) // Header is called once for each header in incoming message. Suppress with // OptNoHeaders. Header(name string, value string, m *Modifier) (Response, error) // Headers is called when all message headers have been processed. Suppress // with OptNoEOH. Headers(h textproto.MIMEHeader, m *Modifier) (Response, error) // BodyChunk is called to process next message body chunk data (up to 64KB // in size). Suppress with OptNoBody. BodyChunk(chunk []byte, m *Modifier) (Response, error) // Body is called at the end of each message. All changes to message's // content & attributes must be done here. Body(m *Modifier) (Response, error) // Abort is called is the current message has been aborted. All message data // should be reset to prior to the Helo callback. Connection data should be // preserved. Abort(m *Modifier) error }
Milter is an interface for milter callback handlers.
type Modifier ¶
type Modifier struct { Macros map[string]string Headers textproto.MIMEHeader // contains filtered or unexported fields }
Modifier provides access to Macros, Headers and Body data to callback handlers. It also defines a number of functions that can be used by callback handlers to modify processing of the email message
func (*Modifier) AddHeader ¶
AddHeader appends a new email message header the message
func (*Modifier) AddRecipient ¶
AddRecipient appends a new envelope recipient for current message
func (*Modifier) ChangeFrom ¶
ChangeFrom replaces the FROM envelope header with a new one
func (*Modifier) ChangeHeader ¶
ChangeHeader replaces the header at the specified position with a new one. The index is per name.
func (*Modifier) DeleteRecipient ¶
DeleteRecipient removes an envelope recipient address from message
func (*Modifier) InsertHeader ¶
InsertHeader inserts the header at the specified position
func (*Modifier) Quarantine ¶
Quarantine a message by giving a reason to hold it
func (*Modifier) ReplaceBody ¶
ReplaceBody substitutes message body with provided body
type ModifyActCode ¶
type ModifyActCode byte
const ( ActAddRcpt ModifyActCode = '+' // SMFIR_ADDRCPT ActDelRcpt ModifyActCode = '-' // SMFIR_DELRCPT ActReplBody ModifyActCode = 'b' // SMFIR_ACCEPT ActAddHeader ModifyActCode = 'h' // SMFIR_ADDHEADER ActChangeHeader ModifyActCode = 'm' // SMFIR_CHGHEADER ActInsertHeader ModifyActCode = 'i' // SMFIR_INSHEADER ActQuarantine ModifyActCode = 'q' // SMFIR_QUARANTINE // [v6] ActChangeFrom ModifyActCode = 'e' // SMFIR_CHGFROM )
type ModifyAction ¶
type ModifyAction struct { Code ModifyActCode // Recipient to add/remove if Code == ActAddRcpt or ActDelRcpt. Rcpt string // New envelope sender if Code = ActChangeFrom. From string // ESMTP arguments for envelope sender if Code = ActChangeFrom. FromArgs []string // Portion of body to be replaced if Code == ActReplBody. Body []byte // Index of the header field to be changed if Code = ActChangeHeader or Code = ActInsertHeader. // Index is 1-based and is per value of HdrName. // E.g. HeaderIndex = 3 and HdrName = "DKIM-Signature" mean "change third // DKIM-Signature field". Order is the same as of HeaderField calls. HeaderIndex uint32 // Header field name to be added/changed if Code == ActAddHeader or // ActChangeHeader or ActInsertHeader. HeaderName string // Header field value to be added/changed if Code == ActAddHeader or // ActChangeHeader or ActInsertHeader. If set to empty string - the field // should be removed. HeaderValue string // Quarantine reason if Code == ActQuarantine. Reason string }
type NoOpMilter ¶
type NoOpMilter struct{}
NoOpMilter is a dummy Milter implementation that does nothing.
func (NoOpMilter) Abort ¶
func (NoOpMilter) Abort(m *Modifier) error
func (NoOpMilter) Body ¶
func (NoOpMilter) Body(m *Modifier) (Response, error)
func (NoOpMilter) BodyChunk ¶
func (NoOpMilter) BodyChunk(chunk []byte, m *Modifier) (Response, error)
func (NoOpMilter) Connect ¶
func (NoOpMilter) Connect(host string, family string, port uint16, addr net.IP, m *Modifier) (Response, error)
func (NoOpMilter) Header ¶
func (NoOpMilter) Headers ¶
func (NoOpMilter) Headers(h textproto.MIMEHeader, m *Modifier) (Response, error)
func (NoOpMilter) Helo ¶
func (NoOpMilter) Helo(name string, m *Modifier) (Response, error)
func (NoOpMilter) MailFrom ¶
func (NoOpMilter) MailFrom(from string, m *Modifier) (Response, error)
func (NoOpMilter) RcptTo ¶
func (NoOpMilter) RcptTo(rcptTo string, m *Modifier) (Response, error)
type OptAction ¶
type OptAction uint32
OptAction sets which actions the milter wants to perform. Multiple options can be set using a bitmask.
const ( OptAddHeader OptAction = 1 << 0 // SMFIF_ADDHDRS OptChangeBody OptAction = 1 << 1 // SMFIF_CHGBODY OptAddRcpt OptAction = 1 << 2 // SMFIF_ADDRCPT OptRemoveRcpt OptAction = 1 << 3 // SMFIF_DELRCPT OptChangeHeader OptAction = 1 << 4 // SMFIF_CHGHDRS OptQuarantine OptAction = 1 << 5 // SMFIF_QUARANTINE // [v6] OptChangeFrom OptAction = 1 << 6 // SMFIF_CHGFROM OptAddRcptWithArgs OptAction = 1 << 7 // SMFIF_ADDRCPT_PAR OptSetSymList OptAction = 1 << 8 // SMFIF_SETSYMLIST )
Set which actions the milter wants to perform.
type OptProtocol ¶
type OptProtocol uint32
OptProtocol masks out unwanted parts of the SMTP transaction. Multiple options can be set using a bitmask.
const ( OptNoConnect OptProtocol = 1 << 0 // SMFIP_NOCONNECT OptNoHelo OptProtocol = 1 << 1 // SMFIP_NOHELO OptNoMailFrom OptProtocol = 1 << 2 // SMFIP_NOMAIL OptNoRcptTo OptProtocol = 1 << 3 // SMFIP_NORCPT OptNoBody OptProtocol = 1 << 4 // SMFIP_NOBODY OptNoHeaders OptProtocol = 1 << 5 // SMFIP_NOHDRS OptNoEOH OptProtocol = 1 << 6 // SMFIP_NOEOH OptNoUnknown OptProtocol = 1 << 8 // SMFIP_NOUNKNOWN OptNoData OptProtocol = 1 << 9 // SMFIP_NODATA // [v6] MTA supports ActSkip OptSkip OptProtocol = 1 << 10 // SMFIP_SKIP // [v6] Filter wants rejected RCPTs OptRcptRej OptProtocol = 1 << 11 // SMFIP_RCPT_REJ // Milter will not send action response for the following MTA messages OptNoHeaderReply OptProtocol = 1 << 7 // SMFIP_NR_HDR, SMFIP_NOHREPL // [v6] OptNoConnReply OptProtocol = 1 << 12 // SMFIP_NR_CONN OptNoHeloReply OptProtocol = 1 << 13 // SMFIP_NR_HELO OptNoMailReply OptProtocol = 1 << 14 // SMFIP_NR_MAIL OptNoRcptReply OptProtocol = 1 << 15 // SMFIP_NR_RCPT OptNoDataReply OptProtocol = 1 << 16 // SMFIP_NR_DATA OptNoUnknownReply OptProtocol = 1 << 17 // SMFIP_NR_UNKN OptNoEOHReply OptProtocol = 1 << 18 // SMFIP_NR_EOH OptNoBodyReply OptProtocol = 1 << 19 // SMFIP_NR_BODY // [v6] OptHeaderLeadingSpace OptProtocol = 1 << 20 // SMFIP_HDR_LEADSPC )
type ProtoFamily ¶
type ProtoFamily byte
const ( FamilyUnknown ProtoFamily = 'U' // SMFIA_UNKNOWN FamilyUnix ProtoFamily = 'L' // SMFIA_UNIX FamilyInet ProtoFamily = '4' // SMFIA_INET FamilyInet6 ProtoFamily = '6' // SMFIA_INET6 )
type Response ¶
Response represents a response structure returned by callback handlers to indicate how the milter server should proceed
type Server ¶
type Server struct { NewMilter func() Milter Actions OptAction Protocol OptProtocol // contains filtered or unexported fields }
Server is a milter server.
func (*Server) Close ¶
func (*Server) Serve ¶
Serve starts the server.
type SimpleResponse ¶
type SimpleResponse byte
SimpleResponse type to define list of pre-defined responses
func (SimpleResponse) Continue ¶
func (r SimpleResponse) Continue() bool
Continue to process milter messages only if current code is Continue
func (SimpleResponse) Response ¶
func (r SimpleResponse) Response() *Message
Response returns a Message object reference
Source Files ¶
client.go cstrings.go message.go milter.go modifier.go response.go server.go session.go
Directories ¶
Path | Synopsis |
---|---|
cmd | |
cmd/milter-check |
- Version
- v0.4.1 (latest)
- Published
- May 12, 2024
- Platform
- js/wasm
- Imports
- 13 packages
- Last checked
- now –
Tools for package owners.