smtpd

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Feb 18, 2023 License: MIT Imports: 17 Imported by: 0

README

License GoDoc Go Report Card

Package smtpd implements a LMTP, SMTP and ESMTP server library in golang.

This is a fork of chrj/smtpd I just added LMTP, most work must be credited to Christian Joergensen

Features

  • STARTTLS (using crypto/tls)
  • Authentication (PLAIN/LOGIN, only after STARTTLS)
  • XCLIENT and PROXY protocol (for running behind a proxy)
  • Connection, HELO, sender and recipient checks for rejecting e-mails using callbacks
  • Configurable limits for: connection count, message size and recipient count
  • Hands incoming e-mail off to a configured callback function

Feedback

If you end up using this package or have any feedback, I'd very much like to hear about it. You can reach me by email.

Documentation

Overview

Package smtpd implements an LMTP and SMTP server with support for STARTTLS, authentication (PLAIN/LOGIN), XCLIENT and optional restrictions on the different stages of the SMTP session.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrServerClosed = errors.New("smtp: Server closed")

ErrServerClosed is returned by the Server's Serve and ListenAndServe, methods after a call to Shutdown.

Functions

This section is empty.

Types

type Envelope

type Envelope struct {
	Sender     string
	Recipients []string
	Data       []byte
}

Envelope holds a message

func (*Envelope) AddReceivedLine

func (env *Envelope) AddReceivedLine(peer Peer, addrFor string)

AddReceivedLine prepends a Received header to the Data

type Error

type Error struct {
	Code    int    // The integer error code
	Message string // The error message
}

Error represents an Error reported in the SMTP session.

func (Error) Error

func (e Error) Error() string

Error returns a string representation of the SMTP error

type Peer

type Peer struct {
	HeloName   string               // Server name used in LHLO/HELO/EHLO command
	Username   string               // Username from authentication, if authenticated
	Password   string               // Password from authentication, if authenticated
	Protocol   Protocol             // Protocol used, LMTP,SMTP or ESMTP
	ServerName string               // A copy of Server.Hostname
	Addr       net.Addr             // Network address
	TLS        *tls.ConnectionState // TLS Connection details, if on TLS
}

Peer represents the client connecting to the server

type Protocol

type Protocol string

Protocol represents the protocol used in the SMTP session

const (
	// LMTP
	LMTP Protocol = "LMTP"

	// SMTP
	SMTP Protocol = "SMTP"

	// Extended SMTP
	ESMTP Protocol = "ESMTP"
)

type Server

type Server struct {
	Hostname       string // Server hostname. (default: "localhost.localdomain")
	WelcomeMessage string // Initial server banner. (default: "<hostname> ESMTP ready.")

	ReadTimeout  time.Duration // Socket timeout for read operations. (default: 60s)
	WriteTimeout time.Duration // Socket timeout for write operations. (default: 60s)
	DataTimeout  time.Duration // Socket timeout for DATA command (default: 5m)

	MaxConnections int // Max concurrent connections, use -1 to disable. (default: 100)
	MaxMessageSize int // Max message size in bytes. (default: 10240000)
	MaxRecipients  int // Max RCPT TO calls for each envelope. (default: 100)

	// New e-mails are handed off to this function.
	// Can be left empty for a NOOP server.
	// If an error is returned, it will be reported in the SMTP session.
	Handler func(peer Peer, env Envelope) error

	// Enable various checks during the SMTP session.
	// Can be left empty for no restrictions.
	// If an error is returned, it will be reported in the SMTP session.
	// Use the Error struct for access to error codes.
	ConnectionChecker func(peer Peer) error              // Called upon new connection.
	HeloChecker       func(peer Peer, name string) error // Called after HELO/EHLO.
	SenderChecker     func(peer Peer, addr string) error // Called after MAIL FROM.
	RecipientChecker  func(peer Peer, addr string) error // Called after each RCPT TO.

	// Enable PLAIN/LOGIN authentication, only available after STARTTLS.
	// Can be left empty for no authentication support.
	Authenticator func(peer Peer, username, password string) error

	EnableXCLIENT       bool // Enable XCLIENT support (default: false)
	EnableProxyProtocol bool // Enable proxy protocol support (default: false)

	TLSConfig *tls.Config // Enable STARTTLS support.
	ForceTLS  bool        // Force STARTTLS usage.

	ProtocolLogger *log.Logger
	// contains filtered or unexported fields
}

Server defines the parameters for running the SMTP server

Example
package main

import (
	"errors"
	"net/smtp"
	"strings"

	"git.hansaray.pw/go/smtpd"
)

func main() {
	var server *smtpd.Server

	// No-op server. Accepts and discards
	server = &smtpd.Server{}
	server.ListenAndServe("127.0.0.1:10025")

	// Relay server. Accepts only from single IP address and forwards using the Gmail smtp
	server = &smtpd.Server{

		HeloChecker: func(peer smtpd.Peer, name string) error {
			if !strings.HasPrefix(peer.Addr.String(), "42.42.42.42:") {
				return errors.New("Denied")
			}
			return nil
		},

		Handler: func(peer smtpd.Peer, env smtpd.Envelope) error {

			return smtp.SendMail(
				"smtp.gmail.com:587",
				smtp.PlainAuth(
					"",
					"username@gmail.com",
					"password",
					"smtp.gmail.com",
				),
				env.Sender,
				env.Recipients,
				env.Data,
			)

		},
	}

	server.ListenAndServe("127.0.0.1:10025")
}
Output:

func (*Server) Address

func (srv *Server) Address() net.Addr

Address returns the listening address of the server

func (*Server) ListenAndServe

func (srv *Server) ListenAndServe(addr string) error

ListenAndServe starts the SMTP server and listens on the address provided

func (*Server) Serve

func (srv *Server) Serve(l net.Listener) error

Serve starts the SMTP server and listens on the Listener provided

func (*Server) Shutdown

func (srv *Server) Shutdown(wait bool) error

Shutdown instructs the server to shutdown, starting by closing the associated listener. If wait is true, it will wait for the shutdown to complete. If wait is false, Wait must be called afterwards.

func (*Server) Wait

func (srv *Server) Wait() error

Wait waits for all client connections to close and the server to finish shutting down.

Jump to

Keyboard shortcuts

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