milter

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2020 License: BSD-2-Clause Imports: 13 Imported by: 6

README

go-milter

GoDoc

A Go library to write mail filters.

License

BSD 2-Clause

Documentation

Overview

Package milter provides an interface to implement milter mail filters

Index

Constants

View Source
const (
	RespAccept   = SimpleResponse(ActAccept)
	RespContinue = SimpleResponse(ActContinue)
	RespDiscard  = SimpleResponse(ActDiscard)
	RespReject   = SimpleResponse(ActReject)
	RespTempFail = SimpleResponse(ActTempFail)
)

Define standard responses with no data

View Source
const MaxBodyChunk = 65535

Variables

View Source
var ErrServerClosed = errors.New("milter: server closed")

ErrServerClosed is returned by the Server's Serve method after a call to Close.

Functions

This section is empty.

Types

type Action added in v0.2.0

type Action struct {
	Code ActionCode

	// SMTP code if Code == ActReplyCode.
	SMTPCode int
	// Reply text if Code == ActReplyCode.
	SMTPText string
}

type ActionCode added in v0.2.0

type ActionCode byte
const (
	ActAccept    ActionCode = 'a'
	ActContinue  ActionCode = 'c'
	ActDiscard   ActionCode = 'd'
	ActReject    ActionCode = 'r'
	ActTempFail  ActionCode = 't'
	ActReplyCode ActionCode = 'y'
)

type Client added in v0.2.0

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 added in v0.2.0

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 added in v0.2.0

func NewDefaultClient(network, address string) *Client

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 added in v0.2.0

func (c *Client) Close() error

func (*Client) Session added in v0.2.0

func (c *Client) Session() (*ClientSession, error)

type ClientOptions added in v0.2.0

type ClientOptions struct {
	Dialer       Dialer
	ReadTimeout  time.Duration
	WriteTimeout time.Duration
	ActionMask   OptAction
	ProtocolMask OptProtocol
}

type ClientSession added in v0.2.0

type ClientSession struct {

	// Bitmask of negotiated action options.
	ActionOpts OptAction

	// Bitmask of negotiated protocol options.
	ProtocolOpts OptProtocol
	// contains filtered or unexported fields
}

func (*ClientSession) ActionOption added in v0.2.0

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 added in v0.2.0

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.

func (*ClientSession) BodyReadFrom added in v0.2.0

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 added in v0.2.0

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 added in v0.2.0

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 added in v0.2.0

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 added in v0.2.0

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 added in v0.2.0

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 added in v0.2.0

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 added in v0.2.0

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 added in v0.2.0

func (s *ClientSession) Macros(code Code, kv ...string) error

func (*ClientSession) Mail added in v0.2.0

func (s *ClientSession) Mail(sender string, esmtpArgs []string) (*Action, error)

func (*ClientSession) ProtocolOption added in v0.2.0

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 added in v0.2.0

func (s *ClientSession) Rcpt(rcpt string, esmtpArgs []string) (*Action, error)

type Code added in v0.2.0

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
)

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 added in v0.2.0

type Dialer interface {
	Dial(network string, addr string) (net.Conn, error)
}

type Message

type Message struct {
	Code byte
	Data []byte
}

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)
}

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

func (m *Modifier) AddHeader(name, value string) error

AddHeader appends a new email message header the message

func (*Modifier) AddRecipient

func (m *Modifier) AddRecipient(r string) error

AddRecipient appends a new envelope recipient for current message

func (*Modifier) ChangeFrom

func (m *Modifier) ChangeFrom(value string) error

ChangeFrom replaces the FROM envelope header with a new one

func (*Modifier) ChangeHeader

func (m *Modifier) ChangeHeader(index int, name, value string) error

ChangeHeader replaces the header at the specified position with a new one. The index is per name.

func (*Modifier) DeleteRecipient

func (m *Modifier) DeleteRecipient(r string) error

DeleteRecipient removes an envelope recipient address from message

func (*Modifier) InsertHeader

func (m *Modifier) InsertHeader(index int, name, value string) error

InsertHeader inserts the header at the specified position

func (*Modifier) Quarantine

func (m *Modifier) Quarantine(reason string) error

Quarantine a message by giving a reason to hold it

func (*Modifier) ReplaceBody

func (m *Modifier) ReplaceBody(body []byte) error

ReplaceBody substitutes message body with provided body

type ModifyActCode added in v0.2.0

type ModifyActCode byte
const (
	ActAddRcpt      ModifyActCode = '+'
	ActDelRcpt      ModifyActCode = '-'
	ActReplBody     ModifyActCode = 'b'
	ActAddHeader    ModifyActCode = 'h'
	ActChangeHeader ModifyActCode = 'm'
	ActInsertHeader ModifyActCode = 'i'
	ActChangeFrom   ModifyActCode = 'e'
	ActQuarantine   ModifyActCode = 'q'
)

type ModifyAction added in v0.2.0

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 OptAction

type OptAction uint32

OptAction sets which actions the milter wants to perform. Multiple options can be set using a bitmask.

const (
	OptAddHeader    OptAction = 0x01
	OptChangeBody   OptAction = 0x02
	OptAddRcpt      OptAction = 0x04
	OptRemoveRcpt   OptAction = 0x08
	OptChangeHeader OptAction = 0x10
	OptQuarantine   OptAction = 0x20
	OptChangeFrom   OptAction = 0x40
)

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 = 0x01
	OptNoHelo     OptProtocol = 0x02
	OptNoMailFrom OptProtocol = 0x04
	OptNoRcptTo   OptProtocol = 0x08
	OptNoBody     OptProtocol = 0x10
	OptNoHeaders  OptProtocol = 0x20
	OptNoEOH      OptProtocol = 0x40
)

mask out unwanted parts of the SMTP transaction

type ProtoFamily added in v0.2.0

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

type Response interface {
	Response() *Message
	Continue() bool
}

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 (s *Server) Close() error

func (*Server) Serve

func (s *Server) Serve(ln net.Listener) error

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

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL