milter

package module
v1.2.1 Latest Latest
Warning

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

Go to latest
Published: Feb 4, 2020 License: BSD-2-Clause Imports: 13 Imported by: 0

README

GoDoc

milter

This is a fork of github.com/phalaaxx/milter, added the following pull requests:

and also _test cases using my milterclient library.

Added the functions in the interface:
  • Init() is called on begin of a new Mail, before Connect() and before MailFrom() and also on RSET (abort command), so you can cleanup and init.
  • Init now has a sessionID and a mailID
  • Disconnect() which is called when the client disconnects (if you have a concurrent session counter you can decrease the counter there, this was not possible before)
  • Logger interface to inject a custom logger
  • Errors exported
  • Changed: EnvFrom and RcptTo addresses are now always converted to lowercase
  • Added all Protocol Options and Actions from libmilter (session.go)
  • Added SymListFactory to Set the list of macros that the milter wants to receive from the MTA for a protocol stage
  • Refactored to common consts names for Milter Commands

Documentation

Overview

A Go library for milter support

Index

Constants

View Source
const (
	SMFIC_ABORT   = 'A' // Abort current filter checks
	SMFIC_BODY    = 'B' // Body chunk
	SMFIC_CONNECT = 'C' // SMTP connection information
	SMFIC_MACRO   = 'D' // Define macros
	SMFIC_BODYEOB = 'E' // End of body marker
	SMFIC_HELO    = 'H' // HELO/EHLO name
	SMFIC_QUIT_NC = 'K' // QUIT but new connection follows
	SMFIC_HEADER  = 'L' // Mail header
	SMFIC_MAIL    = 'M' // MAIL FROM: information
	SMFIC_EOH     = 'N' // End of headers marker
	SMFIC_OPTNEG  = 'O' // Option negotiation
	SMFIC_QUIT    = 'Q' // Quit milter communication
	SMFIC_RCPT    = 'R' // RCPT TO: information
	SMFIC_DATA    = 'T' // DATA
	SMFIC_UNKNOWN = 'U' // Any unknown command

	SMFIR_ADDRCPT     = '+' // Add recipient (modification action)
	SMFIR_DELRCPT     = '-' // Remove recipient (modification action)
	SMFIR_ADDRCPT_PAR = '2' // Add recipient (incl. ESMTP args)
	SMFIR_SHUTDOWN    = '4' // 421: shutdown (internal to MTA)
	SMFIR_ACCEPT      = 'a' // Accept message completely (accept/reject action)
	SMFIR_REPLBODY    = 'b' // Replace body (modification action)
	SMFIR_CONTINUE    = 'c' // Accept and keep processing (accept/reject action)
	SMFIR_DISCARD     = 'd' // Set discard flag for entire message (accept/reject action)
	SMFIR_CHGFROM     = 'e' // Change envelope sender (from)
	SMFIR_CONN_FAIL   = 'f' // Cause a connection failure
	SMFIR_ADDHEADER   = 'h' // Add header (modification action)
	SMFIR_INSHEADER   = 'i' // Insert header
	SMFIR_SETSYMLIST  = 'l' // Set list of symbols (macros)
	SMFIR_CHGHEADER   = 'm' // Change header (modification action)
	SMFIR_PROGRESS    = 'p' // Progress (asynchronous action)
	SMFIR_QUARANTINE  = 'q' // Quarantine message (modification action)
	SMFIR_REJECT      = 'r' // Reject command/recipient with a 5xx (accept/reject action)
	SMFIR_SKIP        = 's' // Skip
	SMFIR_TEMPFAIL    = 't' // Reject command/recipient with a 4xx (accept/reject action)
	SMFIR_REPLYCODE   = 'y' // Send specific Nxx reply message (accept/reject action)

	SMFIA_INET    = '4'
	SMFIA_INET6   = '6'
	SMFIA_UNIX    = 'L'
	SMFIA_UNKNOWN = 'U'
)
View Source
const (
	SMFIS_KEEP    = uint32(20)
	SMFIS_ABORT   = uint32(21)
	SMFIS_OPTIONS = uint32(22)
	SMFIS_NOREPLY = uint32(7)
)
View Source
const (
	// set which actions the milter wants to perform
	OptNone           OptAction = 0x00  /* SMFIF_NONE no flags */
	OptAddHeader      OptAction = 0x01  /* SMFIF_ADDHDRS filter may add headers */
	OptChangeBody     OptAction = 0x02  /* SMFIF_CHGBODY filter may replace body */
	OptAddRcpt        OptAction = 0x04  /* SMFIF_ADDRCPT filter may add recipients */
	OptRemoveRcpt     OptAction = 0x08  /* SMFIF_DELRCPT filter may delete recipients */
	OptChangeHeader   OptAction = 0x10  /* SMFIF_CHGHDRS filter may change/delete headers */
	OptQuarantine     OptAction = 0x20  /* SMFIF_QUARANTINE filter may quarantine envelope */
	OptChangeFrom     OptAction = 0x40  /* SMFIF_CHGFROM filter may change "from" (envelope sender) */
	OptAddRcptPartial OptAction = 0x80  /* SMFIF_ADDRCPT_PAR filter may add recipients, including ESMTP parameter to the envelope.*/
	OptSetSymList     OptAction = 0x100 /* SMFIF_SETSYMLIST filter can send set of symbols (macros) that it wants */
	// OptAllActions SMFI_CURR_ACTS Set of all actions in the current milter version */
	OptAllActions OptAction = OptAddHeader | OptChangeBody | OptAddRcpt | OptRemoveRcpt | OptChangeHeader | OptQuarantine | OptChangeFrom | OptAddRcptPartial | OptSetSymList

	// mask out unwanted parts of the SMTP transaction
	OptNoConnect    OptProtocol = 0x01       /* SMFIP_NOCONNECT MTA should not send connect info */
	OptNoHelo       OptProtocol = 0x02       /* SMFIP_NOHELO MTA should not send HELO info */
	OptNoMailFrom   OptProtocol = 0x04       /* SMFIP_NOMAIL MTA should not send MAIL info */
	OptNoRcptTo     OptProtocol = 0x08       /* SMFIP_NORCPT MTA should not send RCPT info */
	OptNoBody       OptProtocol = 0x10       /* SMFIP_NOBODY MTA should not send body (chunk) */
	OptNoHeaders    OptProtocol = 0x20       /* SMFIP_NOHDRS MTA should not send headers */
	OptNoEOH        OptProtocol = 0x40       /* SMFIP_NOEOH MTA should not send EOH */
	OptNrHdr        OptProtocol = 0x80       /* SMFIP_NR_HDR SMFIP_NOHREPL No reply for headers */
	OptNoUnknown    OptProtocol = 0x100      /* SMFIP_NOUNKNOWN MTA should not send unknown commands */
	OptNoData       OptProtocol = 0x200      /* SMFIP_NODATA MTA should not send DATA */
	OptSkip         OptProtocol = 0x400      /* SMFIP_SKIP MTA understands SMFIS_SKIP */
	OptRcptRej      OptProtocol = 0x800      /* SMFIP_RCPT_REJ MTA should also send rejected RCPTs */
	OptNrConn       OptProtocol = 0x1000     /* SMFIP_NR_CONN No reply for connect */
	OptNrHelo       OptProtocol = 0x2000     /* SMFIP_NR_HELO No reply for HELO */
	OptNrMailFrom   OptProtocol = 0x4000     /* SMFIP_NR_MAIL No reply for MAIL */
	OptNrRcptTo     OptProtocol = 0x8000     /* SMFIP_NR_RCPT No reply for RCPT */
	OptNrData       OptProtocol = 0x10000    /* SMFIP_NR_DATA No reply for DATA */
	OptNrUnknown    OptProtocol = 0x20000    /* SMFIP_NR_UNKN No reply for UNKNOWN */
	OptNrEOH        OptProtocol = 0x40000    /* SMFIP_NR_EOH No reply for eoh */
	OptNrBody       OptProtocol = 0x80000    /* SMFIP_NR_BODY No reply for body chunk */
	OptHdrLeadSpace OptProtocol = 0x100000   /* SMFIP_HDR_LEADSPC header value leading space */
	OptMDS256K      OptProtocol = 0x10000000 /* SMFIP_MDS_256K MILTER_MAX_DATA_SIZE=256K */
	OptMDS1M        OptProtocol = 0x20000000 /* SMFIP_MDS_1M MILTER_MAX_DATA_SIZE=1M */
)

Define standard responses with no data

Variables

View Source
var (
	ErrCloseSession = errors.New("Stop current milter processing")
	ErrMacroNoData  = errors.New("Macro definition with no data")
)

pre-defined errors

Functions

func Close

func Close()

Close server listener and wait worked process

func RunServer

func RunServer(server net.Listener, logger Logger, init MilterInit, handlers ...func(error)) error

RunServer provides a convenient way to start a milter server Handlers provide way to handle errors from panics With nil handlers panics not recovered

Types

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 code should be SMFIR_REPLYCODE == 'y' data can be "550 5.2.0 mailbox unavailable."

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 Logger

type Logger interface {
	Printf(format string, v ...interface{})
}

Logger is a interface to inject a custom logger

type Message

type Message struct {
	Code byte
	Data []byte
}

Message represents a command sent from milter client

type Milter

type Milter interface {
	// Init is called on begin of a new Mail, before Connect() and before MailFrom()
	// Can be used to Reset session state
	// On MailFrom mailID is available
	Init(sessionID, mailID string)

	// Connect is called to provide SMTP connection data for incoming message
	//   supress with NoConnect
	Connect(host string, family string, port uint16, addr net.IP, m *Modifier) (Response, error)

	// Helo is called to process any HELO/EHLO related filters
	//   supress with NoHelo
	Helo(name string, m *Modifier) (Response, error)

	// MailFrom is called to process filters on envelope FROM address
	//   supress with NoMailForm
	MailFrom(from string, m *Modifier) (Response, error)

	// RcptTo is called to process filters on envelope TO address
	//   supress with NoRcptTo
	RcptTo(rcptTo string, m *Modifier) (Response, error)

	// Header is called once for each header in incoming message
	//   supress with NoHeaders
	Header(name string, value string, m *Modifier) (Response, error)

	// Headers is called when all message headers have been processed
	//   supress with NoHeaders
	Headers(h textproto.MIMEHeader, m *Modifier) (Response, error)

	// BodyChunk is called to process next message body chunk data (up to 64KB in size)
	//   supress with NoBody
	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)

	// Disconnect is called at the end of the message Handling loop
	Disconnect()
}

Milter is an interface for milter callback handlers

type MilterInit

type MilterInit func() (Milter, OptAction, OptProtocol)

MilterInit initializes milter options multiple options can be set using a bitmask

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

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 pecified 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 OptAction

type OptAction uint32

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

type OptProtocol

type OptProtocol uint32

OptProtocol masks out unwanted parts of the SMTP transaction. Multiple options can be set using a bitmask.

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 {
	Listener       net.Listener
	MilterFactory  MilterInit
	ErrHandlers    []func(error)
	Logger         Logger
	SymListFactory *SymListFactory // SymListFactory Optional: Set the list of macros that the milter wants to receive from the MTA for a protocol stage.
	sync.WaitGroup
	// contains filtered or unexported fields
}

Server Milter for handling and processing incoming connections support panic handling via ErrHandler couple of func(error) could be provided for handling error

func (*Server) Close

func (s *Server) Close() error

Close for graceful shutdown Stop accepting new connections And wait until processing connections ends

func (*Server) RunServer

func (s *Server) RunServer() error

RunServer starts milter server via provided listener

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

type Stage added in v1.2.0

type Stage uint32

Stage is for SetSymList, to tell the MTA what Macros in what Stage we need

const (
	SMFIM_CONNECT Stage = iota /* 0 connect */
	SMFIM_HELO                 /* 1 HELO/EHLO */
	SMFIM_ENVFROM              /* 2 MAIL From */
	SMFIM_ENVRCPT              /* 3 RCPT To */
	SMFIM_DATA                 /* 4 DATA */
	SMFIM_EOM                  /* 5 = end of message (final dot) */
	SMFIM_EOH                  /* 6 = end of header */
)

type SymListFactory added in v1.2.0

type SymListFactory struct {
	// contains filtered or unexported fields
}

SymListFactory Factory to Set the list of macros that the milter wants to receive from the MTA for a protocol Stage (stages has the prefix SMFIM_).

func (*SymListFactory) Set added in v1.2.0

func (s *SymListFactory) Set(stage Stage, macros string)

Set the list of macros that the milter wants to receive from the MTA for a protocol Stage (stages has the prefix SMFIM_). list of macros (separated by space). Example: "{rcpt_mailer} {rcpt_host}"

Jump to

Keyboard shortcuts

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