package module
Version: v0.0.0-...-400b30e Latest Latest

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

Go to latest
Published: Oct 16, 2018 License: MIT Imports: 10 Imported by: 0



OpenSMTPD-extras in Go


This is very much Work In Progress. Don't use this for production installations. Much of the filter API in OpenSMTPD is not yet stable, so this package is also subject to change.

We have implemented Filter API version 52, because that's compatible with the most recent portable OpenSMTPD version (6.0.3p1).



Package opensmtpd implements OpenSMTPD APIs


The APIs in OpenSMTPD are not stable and subject to change. The filter versions implemented by this package are tested against OpenSMTPD-portable version 6.0.3.


Hooks for the various SMTP transaction stages. If a filter function is registered for a callback, the OpenSMTPD process expects a reply via the Session.Accept() or Session.Reject() calls. Failing to do so may result in a locked up mail server, you have been warned!




View Source
const (
	FilterOK = iota
View Source
const (
	// FilterVersion is the supported filter API version
	FilterVersion = 52

	// QueueVersion is the supported queue API version
	QueueVersion = 2

	// TableVersion is the supported table API version
	TableVersion = 2
View Source
const (
	ServiceNone        = 0x000
	ServiceAlias       = 0x001
	ServiceDomain      = 0x002
	ServiceCredentials = 0x004
	ServiceNetaddr     = 0x008
	ServiceUserinfo    = 0x010
	ServiceSource      = 0x020
	ServiceMailaddr    = 0x040
	ServiceAddrname    = 0x080
	ServiceMailaddrMap = 0x100
	ServiceRelayHost   = 0x200
	ServiceString      = 0x400
	ServiceAny         = 0xfff



View Source
var (
	// Debug flag
	Debug bool


This section is empty.


type ConnectQuery

type ConnectQuery struct {
	Local, Remote net.Addr
	Hostname      string

ConnectQuery are the QUERY_CONNECT arguments

func (ConnectQuery) String

func (q ConnectQuery) String() string

type Dict

type Dict map[string]interface{}

Dict is a key-value mapping

type Filter

type Filter struct {
	// Connect callback
	Connect func(*Session, *ConnectQuery) error

	// HELO callback
	HELO func(*Session, string) error

	// MAIL FROM callback
	MAIL func(*Session, string, string) error

	// RCPT TO callback
	RCPT func(*Session, string, string) error

	// DATA callback
	DATA func(*Session) error

	// DataLine callback
	DataLine func(*Session, string) error

	// EOM (end of message) callback
	EOM func(*Session, uint32) error

	// Reset callback
	Reset func(*Session) error

	// Disconnect callback
	Disconnect func(*Session) error

	// Commit callback
	Commit func(*Session) error

	Name    string
	Version uint32
	// contains filtered or unexported fields

Filter implements the OpenSMTPD filter API

// Build our filter
filter := &Filter{
	HELO: func(session *Session, helo string) error {
		if helo == "test" {
			return session.Reject(FilterOK, 0)
		return session.Accept()

// Add another hook
filter.MAIL = func(session *Session, user, domain string) error {
	if strings.ToLower(domain) == "" {
		return session.Reject(FilterOK, 0)
	return session.Accept()

// Register our filter with smtpd. This step is optional and will
// be performed by Serve() if omitted.
if err := filter.Register(); err != nil {

// And keep serving until smtpd stops

func (*Filter) Register

func (f *Filter) Register() error

Register our filter with OpenSMTPD

func (*Filter) Serve

func (f *Filter) Serve() error

Serve communicates with OpenSMTPD in a loop, until either one of the parties closes stdin.

type Session

type Session struct {
	ID uint64
	// contains filtered or unexported fields

func NewSession

func NewSession(f *Filter, id uint64) *Session

func (*Session) Accept

func (s *Session) Accept() error

func (*Session) AcceptCode

func (s *Session) AcceptCode(code int, line string) error

func (*Session) Reject

func (s *Session) Reject(status, code int) error

func (*Session) RejectCode

func (s *Session) RejectCode(status, code int, line string) error

type Sockaddr

type Sockaddr []byte

Sockaddr emulates the mess that is struct sockaddr

func (Sockaddr) IP

func (sa Sockaddr) IP() net.IP

func (Sockaddr) Network

func (sa Sockaddr) Network() string

func (Sockaddr) Port

func (sa Sockaddr) Port() uint16

func (Sockaddr) String

func (sa Sockaddr) String() string

type Table

type Table struct {
	// Update callback
	Update func() (int, error)

	// Check callback
	Check func(service int, params Dict, key string) (int, error)

	// Lookup callback
	Lookup func(service int, params Dict, key string) (string, error)

	// Fetch callback
	Fetch func(service int, params Dict) (string, error)

	// Close callback, called at stop
	Close func() error
	// contains filtered or unexported fields

Table implements the OpenSMTPD table API

// In smtpd.conf:
//   table aliases <name-of-filter>:
//   accept for local alias <aliases> ...

aliases := map[string]string{
	"root": "",

table := &Table{
	Lookup: func(service int, params Dict, key string) (string, error) {
		// We are only valid for aliases
		if service&ServiceAlias != 0 {
			return aliases[key], nil
		return "", nil

func (*Table) Serve

func (t *Table) Serve() error


Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
t or T : Toggle theme light dark auto
y or Y : Canonical URL