smtpserver

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2020 License: AGPL-3.0 Imports: 24 Imported by: 0

Documentation

Index

Constants

View Source
const (
	SecurityPass string = "pass"
	SecurityFail string = "fail"
)

Variables

View Source
var (
	ErrHashFail            = errors.New("error while hashing password")
	ErrInvalidDestination  = errors.New("invalid destination")
	ErrParsingError        = errors.New("parsing error")
	ErrDomainMisalignment  = errors.New("domains not aligned")
	ErrSMTPClientInitFail  = errors.New("could not connect to outbound SMTP server")
	ErrSMTPClientCloseFail = errors.New("could not close connection to outbound SMTP server")
	ErrSMTPClientSendFail  = errors.New("could not send SMTP message")
	ErrMaxSizeExceeded     = errors.New("maximum message size exceeded")
	ErrValidationError     = errors.New("validation failed")
	ErrMissingDependency   = errors.New("missing dependency")
)
View Source
var (
	ErrSMTPInvalidDestination = &smtp.SMTPError{
		Code:         552,
		EnhancedCode: smtp.EnhancedCode{5, 3, 4},
		Message:      "Invalid destination",
	}

	ErrSMTPServerError = &smtp.SMTPError{
		Code:         552,
		EnhancedCode: smtp.EnhancedCode{5, 3, 4},
		Message:      "Server error",
	}
)

TODO research valid SMTP codes.

Functions

func GetDKIMStatus

func GetDKIMStatus(raw []byte, fromHeader string) (status, alignment string, statusErr, alignmentErr error)

func GetDomainAlignment

func GetDomainAlignment(domain1, domain2 string, strict bool) (string, error)

func GetIP

func GetIP(a net.Addr) (net.IP, error)

func GetSPFStatus

func GetSPFStatus(remoteIP net.IP, helo, from, fromHeader string) (status, alignment string, statusErr, alignmentErr error)

func GetTLSConfig

func GetTLSConfig(c *SMTPTLSConfig) (*tls.Config, error)

func LimitedRead

func LimitedRead(r io.Reader, size int64) ([]byte, error)

LimitedRead validates a mail message is no more than 'size' bytes, and returns a new io.Reader containing a copy of the original bytes.

func NewSMTPClient

func NewSMTPClient(c *SMTPClientConfig) (*gomail.Dialer, error)

NewSMTPClient initializes and tests a new outbound SMTP server.

func NewSMTPServer

func NewSMTPServer(ss *SMTPService, tc *tls.Config, port, maxSize int, hostname string) *smtp.Server

func ValidateDomainWhitelist

func ValidateDomainWhitelist(mailbox *letterbox.Mailbox, from *Address) error

Types

type Address

type Address struct {
	mail.Address
	Mailbox string
	Domain  string
}

func SplitAddr

func SplitAddr(address string) (*Address, error)

type SMTPBackend

type SMTPBackend struct {
	Service *SMTPService
}

The SMTPBackend implements SMTP server methods.

func (*SMTPBackend) AnonymousLogin

func (bkd *SMTPBackend) AnonymousLogin(state *smtp.ConnectionState) (smtp.Session, error)

AnonymousLogin requires clients to authenticate using SMTP AUTH before sending emails.

func (*SMTPBackend) Login

func (bkd *SMTPBackend) Login(state *smtp.ConnectionState, username, password string) (smtp.Session, error)

Login handles a login command with username and password.

type SMTPClientConfig

type SMTPClientConfig struct {
	DomainID uint   `json:"-"`
	Host     string `json:"host,omitempty"`
	Port     int    `json:"port,omitempty"`
	Username string `json:"username,omitempty"`
	Password string `json:"password,omitempty"`
}

func (*SMTPClientConfig) Validate

func (c *SMTPClientConfig) Validate() error

type SMTPConfig

type SMTPConfig struct {
	Hostname string           `json:"hostname,omitempty"`
	Port     int              `json:"port,omitempty"`
	MaxSize  string           `json:"max_size,omitempty"`
	Outbound SMTPClientConfig `json:"outbound,omitempty"`
	TLS      *SMTPTLSConfig   `json:"tls,omitempty"`
}

func (*SMTPConfig) Validate

func (c *SMTPConfig) Validate() error

type SMTPLimitedReader

type SMTPLimitedReader struct {
	R io.Reader // underlying reader
	N int64     // max bytes remaining
}

A SMTPLimitedReader reads from R but limits the amount of data returned to just N bytes. Each call to Read updates N to reflect the new amount remaining. Read returns ErrExceedMaxSize when N <= 0 or EOF when the underlying R returns EOF.

This differs from a LimitedReader only in that this will raise a different error after the max size has been reached, allowing the connection to be dropped.

func (*SMTPLimitedReader) Read

func (l *SMTPLimitedReader) Read(p []byte) (n int, err error)

type SMTPService

type SMTPService struct {
	Config           SMTPConfig
	Server           *smtp.Server
	TLSServer        *smtp.Server
	GlobalSMTPClient *gomail.Dialer
	MaxSize          int64

	// Service Dependencies
	DB     letterbox.Datastore
	Logger *logger.Logger
}

func (*SMTPService) Name

func (ss *SMTPService) Name() string

func (*SMTPService) Start

func (ss *SMTPService) Start() error

func (*SMTPService) Stop

func (ss *SMTPService) Stop() error

type SMTPSession

type SMTPSession struct {
	Service    *SMTPService
	RemoteAddr net.Addr
	Helo       string
	From       string
	To         string
	Mailbox    *letterbox.Mailbox
	User       *letterbox.User
	UserKey    *letterbox.UserKey
}

func (*SMTPSession) CreateProxyMessage

func (s *SMTPSession) CreateProxyMessage(message *letterbox.Message, logger *zap.SugaredLogger) (*letterbox.Message, error)

func (*SMTPSession) Data

func (s *SMTPSession) Data(r io.Reader) error

func (*SMTPSession) ForwardEmail

func (s *SMTPSession) ForwardEmail(message *letterbox.Message, logger *zap.SugaredLogger) error

func (*SMTPSession) Logout

func (s *SMTPSession) Logout() error

func (*SMTPSession) Mail

func (s *SMTPSession) Mail(from string, opts smtp.MailOptions) error

func (*SMTPSession) Rcpt

func (s *SMTPSession) Rcpt(to string) error

func (*SMTPSession) Reset

func (s *SMTPSession) Reset()

type SMTPTLSConfig

type SMTPTLSConfig struct {
	// The certificate string
	Cert string `json:"cert,omitempty"`

	// The (unencrypted) private key string
	Key string `json:"key,omitempty"`

	// The path to the file containing the certificate
	CertFile string `json:"cert_file,omitempty"`

	// The path to the file containing the (unencrypted) private key
	KeyFile string `json:"key_file,omitempty"`

	// The port to use for the TLS-only SMTPS server
	// This server is wrapped with TLS, and doesn't use the STARTTLS function
	// See RFC8314
	Port int `json:"port,omitempty"`
}

func (*SMTPTLSConfig) Validate

func (c *SMTPTLSConfig) Validate() error

type SecurityChecks

type SecurityChecks struct {
	SPFResult     string
	SPFAlignment  string
	DKIMStatus    string
	DKIMAlignment string
}

func GetSecurityChecks

func GetSecurityChecks(mailLog *zap.SugaredLogger, s *SMTPSession, remoteIP net.IP, raw []byte, fromHeader string) *SecurityChecks

TODO hide these checks behind some interfaces so we can still unit-test them.

Jump to

Keyboard shortcuts

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