1/*2Maddy Mail Server - Composable all-in-one email server.3Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors45This program is free software: you can redistribute it and/or modify6it under the terms of the GNU General Public License as published by7the Free Software Foundation, either version 3 of the License, or8(at your option) any later version.910This program is distributed in the hope that it will be useful,11but WITHOUT ANY WARRANTY; without even the implied warranty of12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13GNU General Public License for more details.1415You should have received a copy of the GNU General Public License16along with this program. If not, see <https://www.gnu.org/licenses/>.17*/1819package module2021import (22 "context"2324 "github.com/emersion/go-message/textproto"25 "github.com/foxcpp/maddy/framework/buffer"26)2728// Modifier is the module interface for modules that can mutate the29// processed message or its meta-data.30//31// Currently, the message body can't be mutated for efficiency and32// correctness reasons: It would require "rebuffering" (see buffer.Buffer doc),33// can invalidate assertions made on the body contents before modification and34// will break DKIM signatures.35//36// Only message header can be modified. Furthermore, it is highly discouraged for37// modifiers to remove or change existing fields to prevent issues outlined38// above.39//40// Calls on ModifierState are always strictly ordered.41// RewriteRcpt is newer called before RewriteSender and RewriteBody is never called42// before RewriteRcpts. This allows modificator code to save values43// passed to previous calls for use in later operations.44//45// Modules implementing this interface should be registered with "modify." prefix in name.46type Modifier interface {47 // ModStateForMsg initializes modifier "internal" state48 // required for processing of the message.49 ModStateForMsg(ctx context.Context, msgMeta *MsgMetadata) (ModifierState, error)50}5152type ModifierState interface {53 // RewriteSender allows modifier to replace MAIL FROM value.54 // If no changes are required, this method returns its55 // argument, otherwise it returns a new value.56 //57 // Note that per-source/per-destination modifiers are executed58 // after routing decision is made so changed value will have no59 // effect on it.60 //61 // Also note that MsgMeta.OriginalFrom will still contain the original value62 // for purposes of tracing. It should not be modified by this method.63 RewriteSender(ctx context.Context, mailFrom string) (string, error)6465 // RewriteRcpt replaces RCPT TO value.66 // If no changed are required, this method returns its argument as slice,67 // otherwise it returns a slice with 1 or more new values.68 //69 // MsgPipeline will take of populating MsgMeta.OriginalRcpts. RewriteRcpt70 // doesn't do it.71 RewriteRcpt(ctx context.Context, rcptTo string) ([]string, error)7273 // RewriteBody modifies passed Header argument and may optionally74 // inspect the passed body buffer to make a decision on new header field values.75 //76 // There is no way to modify the body and RewriteBody should avoid77 // removing existing header fields and changing their values.78 RewriteBody(ctx context.Context, h *textproto.Header, body buffer.Buffer) error7980 // Close is called after the message processing ends, even if any of the81 // Rewrite* functions return an error.82 Close() error83}