maddy

Fork https://github.com/foxcpp/maddy

git clone git://git.lin.moe/go/maddy.git

  1/*
  2Maddy Mail Server - Composable all-in-one email server.
  3Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors
  4
  5This program is free software: you can redistribute it and/or modify
  6it under the terms of the GNU General Public License as published by
  7the Free Software Foundation, either version 3 of the License, or
  8(at your option) any later version.
  9
 10This program is distributed in the hope that it will be useful,
 11but WITHOUT ANY WARRANTY; without even the implied warranty of
 12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13GNU General Public License for more details.
 14
 15You should have received a copy of the GNU General Public License
 16along with this program.  If not, see <https://www.gnu.org/licenses/>.
 17*/
 18
 19package module
 20
 21import (
 22	"context"
 23
 24	"github.com/emersion/go-message/textproto"
 25	"github.com/emersion/go-msgauth/authres"
 26	"github.com/foxcpp/maddy/framework/buffer"
 27)
 28
 29// Check is the module interface that is meant for read-only (with the
 30// exception of the message header modifications) (meta-)data checking.
 31//
 32// Modules implementing this interface should be registered with "check."
 33// prefix in name.
 34type Check interface {
 35	// CheckStateForMsg initializes the "internal" check state required for
 36	// processing of the new message.
 37	//
 38	// NOTE: Returned CheckState object must be hashable (usable as a map key).
 39	// This is used to deduplicate Check* calls, the easiest way to achieve
 40	// this is to have CheckState as a pointer to some struct, all pointers
 41	// are hashable.
 42	CheckStateForMsg(ctx context.Context, msgMeta *MsgMetadata) (CheckState, error)
 43}
 44
 45// EarlyCheck is an optional module interface that can be implemented
 46// by module implementing Check.
 47//
 48// It is used as an optimization to reject obviously malicious connections
 49// before allocating resources for SMTP session.
 50//
 51// The Status of this check is accept (no error) or reject (error) only, no
 52// advanced handling is available (such as 'quarantine' action and headers
 53// prepending).
 54//
 55// If it s necessary to defer or affect further message processing
 56// without outright killing the session, ConnState.ModData can be
 57// used to store necessary information.
 58//
 59// It may be called multiple times for the same connection if TLS is negotiated
 60// via STARTTLS. In this case, no state will be passed between before-TLS
 61// context to the TLS one.
 62type EarlyCheck interface {
 63	CheckConnection(ctx context.Context, state *ConnState) error
 64}
 65
 66type CheckState interface {
 67	// CheckConnection is executed once when client sends a new message.
 68	CheckConnection(ctx context.Context) CheckResult
 69
 70	// CheckSender is executed once when client sends the message sender
 71	// information (e.g. on the MAIL FROM command).
 72	CheckSender(ctx context.Context, mailFrom string) CheckResult
 73
 74	// CheckRcpt is executed for each recipient when its address is received
 75	// from the client (e.g. on the RCPT TO command).
 76	CheckRcpt(ctx context.Context, rcptTo string) CheckResult
 77
 78	// CheckBody is executed once after the message body is received and
 79	// buffered in memory or on disk.
 80	//
 81	// Check code should use passed mutex when working with the message header.
 82	// Body can be read without locking it since it is read-only.
 83	CheckBody(ctx context.Context, header textproto.Header, body buffer.Buffer) CheckResult
 84
 85	// Close is called after the message processing ends, even if any of the
 86	// Check* functions return an error.
 87	Close() error
 88}
 89
 90type CheckResult struct {
 91	// Reason is the error that is reported to the message source
 92	// if check decided that the message should be rejected.
 93	Reason error
 94
 95	// Reject is the flag that specifies that the message
 96	// should be rejected.
 97	Reject bool
 98
 99	// Quarantine is the flag that specifies that the message
100	// is considered "possibly malicious" and should be
101	// put into Junk mailbox.
102	//
103	// This value is copied into MsgMetadata by the msgpipeline.
104	Quarantine bool
105
106	// AuthResult is the information that is supposed to
107	// be included in Authentication-Results header.
108	AuthResult []authres.Result
109
110	// Header is the header fields that should be
111	// added to the header after all checks.
112	Header textproto.Header
113}