Documentation
¶
Index ¶
- Constants
- Variables
- type Command
- type Protocol
- func (proto *Protocol) Command(command *Command) (reply *Reply)
- func (proto *Protocol) EHLO(args string) (reply *Reply)
- func (proto *Protocol) HELO(args string) (reply *Reply)
- func (proto *Protocol) Parse(line string) (string, *Reply)
- func (proto *Protocol) ParseMAIL(mail string) (string, error)
- func (proto *Protocol) ParseRCPT(rcpt string) (string, error)
- func (proto *Protocol) ProcessCommand(line string) (reply *Reply)
- func (proto *Protocol) ProcessData(line string) (reply *Reply)
- func (proto *Protocol) STARTTLS(args string) (reply *Reply)
- func (proto *Protocol) Start() *Reply
- type Reply
- func ReplyAuthOk() *Reply
- func ReplyAuthResponse(response string) *Reply
- func ReplyBye() *Reply
- func ReplyDataResponse() *Reply
- func ReplyError(err error) *Reply
- func ReplyIdent(ident string) *Reply
- func ReplyInvalidAuth() *Reply
- func ReplyLineTooLong() *Reply
- func ReplyMustIssueSTARTTLSFirst() *Reply
- func ReplyOk(message ...string) *Reply
- func ReplyReadyToStartTLS(callback func()) *Reply
- func ReplyRecipientOk(recipient string) *Reply
- func ReplySenderOk(sender string) *Reply
- func ReplyStorageFailed(reason string) *Reply
- func ReplySyntaxError(response string) *Reply
- func ReplyTooManyRecipients() *Reply
- func ReplyUnrecognisedCommand() *Reply
- func ReplyUnsupportedAuth() *Reply
- type State
Constants ¶
const ( INVALID = State(-1) ESTABLISH = State(iota) AUTHPLAIN AUTHLOGIN AUTHLOGIN2 AUTHCRAMMD5 MAIL RCPT DATA DONE )
SMTP message conversation states
Variables ¶
var StateMap = map[State]string{ INVALID: "INVALID", ESTABLISH: "ESTABLISH", AUTHPLAIN: "AUTHPLAIN", AUTHLOGIN: "AUTHLOGIN", AUTHLOGIN2: "AUTHLOGIN2", AUTHCRAMMD5: "AUTHCRAMMD5", MAIL: "MAIL", RCPT: "RCPT", DATA: "DATA", DONE: "DONE", }
StateMap provides string representations of SMTP conversation states
Functions ¶
This section is empty.
Types ¶
type Command ¶
type Command struct {
// contains filtered or unexported fields
}
Command is a struct representing an SMTP command (verb + arguments)
func ParseCommand ¶
ParseCommand returns a Command from the line string
type Protocol ¶
type Protocol struct { TLSPending bool TLSUpgraded bool State State Message *data.SMTPMessage Hostname string Ident string MaximumLineLength int MaximumRecipients int // LogHandler is called for each log message. If nil, log messages will // be output using log.Printf instead. LogHandler func(message string, args ...interface{}) // MessageReceivedHandler is called for each message accepted by the // SMTP protocol. It must return a MessageID or error. If nil, messages // will be rejected with an error. MessageReceivedHandler func(*data.SMTPMessage) (string, error) // ValidateSenderHandler should return true if the sender is valid, // otherwise false. If nil, all senders will be accepted. ValidateSenderHandler func(from string) bool // ValidateRecipientHandler should return true if the recipient is valid, // otherwise false. If nil, all recipients will be accepted. ValidateRecipientHandler func(to string) bool // ValidateAuthenticationhandler should return true if the authentication // parameters are valid, otherwise false. If nil, all authentication // attempts will be accepted. ValidateAuthenticationHandler func(mechanism string, args ...string) (errorReply *Reply, ok bool) // SMTPVerbFilter is called after each command is parsed, but before // any code is executed. This provides an opportunity to reject unwanted verbs, // e.g. to require AUTH before MAIL SMTPVerbFilter func(verb string, args ...string) (errorReply *Reply) // TLSHandler is called when a STARTTLS command is received. // // It should acknowledge the TLS request and set ok to true. // It should also return a callback which will be invoked after the reply is // sent. E.g., a TCP connection can only perform the upgrade after sending the reply // // Once the upgrade is complete, invoke the done function (e.g., from the returned callback) // // If TLS upgrade isn't possible, return an errorReply and set ok to false. TLSHandler func(done func(ok bool)) (errorReply *Reply, callback func(), ok bool) // GetAuthenticationMechanismsHandler should return an array of strings // listing accepted authentication mechanisms GetAuthenticationMechanismsHandler func() []string // RejectBrokenRCPTSyntax controls whether the protocol accepts technically // invalid syntax for the RCPT command. Set to true, the RCPT syntax requires // no space between `TO:` and the opening `<` RejectBrokenRCPTSyntax bool // RejectBrokenMAILSyntax controls whether the protocol accepts technically // invalid syntax for the MAIL command. Set to true, the MAIL syntax requires // no space between `FROM:` and the opening `<` RejectBrokenMAILSyntax bool // RequireTLS controls whether TLS is required for a connection before other // commands can be issued, applied at the protocol layer. RequireTLS bool // contains filtered or unexported fields }
Protocol is a state machine representing an SMTP session
func NewProtocol ¶
func NewProtocol() *Protocol
NewProtocol returns a new SMTP state machine in INVALID state handler is called when a message is received and should return a message ID
func (*Protocol) Parse ¶
Parse parses a line string and returns any remaining line string and a reply, if a command was found. Parse does nothing until a new line is found.
- TODO decide whether to move this to a buffer inside Protocol sort of like it this way, since it gives control back to the caller
func (*Protocol) ProcessCommand ¶
ProcessCommand processes a line of text as a command It expects the line string to be a properly formed SMTP verb and arguments
func (*Protocol) ProcessData ¶
ProcessData handles content received (with newlines stripped) while in the SMTP DATA state
type Reply ¶
type Reply struct { Status int Done func() // contains filtered or unexported fields }
Reply is a struct representing an SMTP reply (status code + lines)
func ReplyAuthOk ¶
func ReplyAuthOk() *Reply
ReplyAuthOk creates a 235 authentication successful reply
func ReplyAuthResponse ¶
ReplyAuthResponse creates a 334 authentication reply
func ReplyLineTooLong ¶ added in v0.1.1
func ReplyLineTooLong() *Reply
ReplyLineTooLong creates a 500 Line too long reply
func ReplyMustIssueSTARTTLSFirst ¶ added in v0.1.1
func ReplyMustIssueSTARTTLSFirst() *Reply
ReplyMustIssueSTARTTLSFirst creates a 530 reply for RFC3207
func ReplyReadyToStartTLS ¶ added in v0.1.1
func ReplyReadyToStartTLS(callback func()) *Reply
ReplyReadyToStartTLS creates a 220 ready to start TLS reply
func ReplyRecipientOk ¶
ReplyRecipientOk creates a 250 Sender ok reply
func ReplySenderOk ¶
ReplySenderOk creates a 250 Sender ok reply
func ReplyStorageFailed ¶
ReplyStorageFailed creates a 452 error reply
func ReplySyntaxError ¶ added in v0.1.1
ReplySyntaxError creates a 501 Syntax error reply
func ReplyTooManyRecipients ¶ added in v0.1.1
func ReplyTooManyRecipients() *Reply
ReplyTooManyRecipients creates a 552 too many recipients reply
func ReplyUnrecognisedCommand ¶
func ReplyUnrecognisedCommand() *Reply
ReplyUnrecognisedCommand creates a 500 Unrecognised command reply
func ReplyUnsupportedAuth ¶
func ReplyUnsupportedAuth() *Reply
ReplyUnsupportedAuth creates a 504 unsupported authentication reply