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