Home | History | Annotate | Line # | Download | only in cleanup
      1 /*	$NetBSD: cleanup.h,v 1.12 2026/05/09 18:49:15 christos Exp $	*/
      2 
      3 /*++
      4 /* NAME
      5 /*	cleanup 3h
      6 /* SUMMARY
      7 /*	canonicalize and enqueue message
      8 /* SYNOPSIS
      9 /*	#include "cleanup.h"
     10 /* DESCRIPTION
     11 /* .nf
     12 
     13  /*
     14   * System library.
     15   */
     16 #include <sys/time.h>
     17 #include <stdint.h>			/* C99 uint64_t */
     18 
     19  /*
     20   * Utility library.
     21   */
     22 #include <vstring.h>
     23 #include <vstream.h>
     24 #include <argv.h>
     25 #include <nvtable.h>
     26 
     27  /*
     28   * Global library.
     29   */
     30 #include <maps.h>
     31 #include <tok822.h>
     32 #include <been_here.h>
     33 #include <mail_stream.h>
     34 #include <mail_conf.h>
     35 #include <mime_state.h>
     36 #include <string_list.h>
     37 #include <cleanup_user.h>
     38 #include <header_body_checks.h>
     39 #include <dsn_mask.h>
     40 
     41  /*
     42   * Milter library.
     43   */
     44 #include <milter.h>
     45 
     46  /*
     47   * These state variables are accessed by many functions, and there is only
     48   * one instance of each per message.
     49   */
     50 typedef struct CLEANUP_STATE {
     51     VSTRING *attr_buf;			/* storage for named attribute */
     52     VSTRING *temp1;			/* scratch buffer, local use only */
     53     VSTRING *temp2;			/* scratch buffer, local use only */
     54     VSTRING *temp3;			/* scratch buffer, local use only */
     55     VSTRING *stripped_buf;		/* character stripped input */
     56     VSTREAM *src;			/* current input stream */
     57     VSTREAM *dst;			/* current output stream */
     58     MAIL_STREAM *handle;		/* mail stream handle */
     59     char   *queue_name;			/* queue name */
     60     char   *queue_id;			/* queue file basename */
     61     struct timeval arrival_time;	/* arrival time */
     62     char   *fullname;			/* envelope sender full name */
     63     char   *sender;			/* envelope sender address */
     64     char   *recip;			/* envelope recipient address */
     65     char   *orig_rcpt;			/* original recipient address */
     66     char   *return_receipt;		/* return-receipt address */
     67     char   *errors_to;			/* errors-to address */
     68     ARGV   *auto_hdrs;			/* MTA's own header(s) */
     69     ARGV   *hbc_rcpt;			/* header/body checks BCC addresses */
     70     int     flags;			/* processing options, status flags */
     71     int     tflags;			/* User- or MTA-requested tracing */
     72     int     qmgr_opts;			/* qmgr processing options */
     73     int     errs;			/* any badness experienced */
     74     int     err_mask;			/* allowed badness */
     75     uint64_t headers_seen;		/* which headers were seen */
     76     int     hop_count;			/* count of received: headers */
     77     char   *resent;			/* any resent- header seen */
     78     BH_TABLE *dups;			/* recipient dup filter */
     79     void    (*action) (struct CLEANUP_STATE *, int, const char *, ssize_t);
     80     off_t   data_offset;		/* start of message content */
     81     off_t   body_offset;		/* start of body content */
     82     off_t   xtra_offset;		/* start of extra segment */
     83     off_t   cont_length;		/* length including Milter edits */
     84     off_t   sender_pt_offset;		/* replace sender here */
     85     off_t   sender_pt_target;		/* record after sender address */
     86     off_t   append_rcpt_pt_offset;	/* append recipient here */
     87     off_t   append_rcpt_pt_target;	/* target of above record */
     88     off_t   append_hdr_pt_offset;	/* append header here */
     89     off_t   append_hdr_pt_target;	/* target of above record */
     90     off_t   append_meta_pt_offset;	/* append meta record here */
     91     off_t   append_meta_pt_target;	/* target of above record */
     92     ssize_t rcpt_count;			/* recipient count */
     93     char   *reason;			/* failure reason */
     94     char   *smtp_reply;			/* failure reason, SMTP-style */
     95     NVTABLE *attr;			/* queue file attribute list */
     96     MIME_STATE *mime_state;		/* MIME state engine */
     97     int     mime_errs;			/* MIME error flags */
     98     char   *hdr_rewrite_context;	/* header rewrite context */
     99     char   *filter;			/* from header/body patterns */
    100     char   *redirect;			/* from header/body patterns */
    101     char   *message_id;			/* from Message-ID header */
    102     char   *dsn_envid;			/* DSN envelope ID */
    103     int     dsn_ret;			/* DSN full/hdrs */
    104     int     dsn_notify;			/* DSN never/delay/fail/success */
    105     char   *dsn_orcpt;			/* DSN original recipient */
    106     char   *verp_delims;		/* VERP delimiters (optional) */
    107 #ifdef DELAY_ACTION
    108     int     defer_delay;		/* deferred delivery */
    109 #endif
    110 
    111     /*
    112      * Miscellaneous Milter support.
    113      */
    114     MILTERS *milters;			/* mail filters */
    115     const char *client_name;		/* real or ersatz client */
    116     const char *reverse_name;		/* real or ersatz client */
    117     const char *client_addr;		/* real or ersatz client */
    118     int     client_af;			/* real or ersatz client */
    119     const char *client_port;		/* real or ersatz client */
    120     const char *server_addr;		/* real or ersatz server */
    121     const char *server_port;		/* real or ersatz server */
    122     VSTRING *milter_ext_from;		/* externalized sender */
    123     VSTRING *milter_ext_rcpt;		/* externalized recipient */
    124     VSTRING *milter_err_text;		/* milter call-back reply */
    125     VSTRING *milter_dsn_buf;		/* Milter DSN parsing buffer */
    126 
    127     /*
    128      * Support for Milter body replacement requests.
    129      */
    130     struct CLEANUP_REGION *free_regions;/* unused regions */
    131     struct CLEANUP_REGION *body_regions;/* regions with body content */
    132     struct CLEANUP_REGION *curr_body_region;
    133 
    134     /*
    135      * Internationalization, RequireTLS, etc.
    136      */
    137     int     sendopts;			/* what support is desired */
    138     int     reqtls_esmtp_hdr_seen;	/* valid Require-TLS-ESMTP header */
    139 } CLEANUP_STATE;
    140 
    141  /*
    142   * Status flags. Flags 0-15 are reserved for cleanup_user.h.
    143   */
    144 #define CLEANUP_FLAG_INRCPT	(1<<16)	/* Processing recipient records */
    145 #define CLEANUP_FLAG_WARN_SEEN	(1<<17)	/* REC_TYPE_WARN record seen */
    146 #define CLEANUP_FLAG_END_SEEN	(1<<18)	/* REC_TYPE_END record seen */
    147 
    148  /*
    149   * Bit mask for the CLEANUP_STATE.headers_seen member.
    150   */
    151 #define HDRS_SEEN_MASK(hval)		((uint64_t) 1 << (hval))
    152 
    153  /*
    154   * Mappings.
    155   */
    156 extern MAPS *cleanup_comm_canon_maps;
    157 extern MAPS *cleanup_send_canon_maps;
    158 extern MAPS *cleanup_rcpt_canon_maps;
    159 extern int cleanup_comm_canon_flags;
    160 extern int cleanup_send_canon_flags;
    161 extern int cleanup_rcpt_canon_flags;
    162 extern MAPS *cleanup_header_checks;
    163 extern MAPS *cleanup_mimehdr_checks;
    164 extern MAPS *cleanup_nesthdr_checks;
    165 extern MAPS *cleanup_body_checks;
    166 extern MAPS *cleanup_virt_alias_maps;
    167 extern ARGV *cleanup_masq_domains;
    168 extern STRING_LIST *cleanup_masq_exceptions;
    169 extern int cleanup_masq_flags;
    170 extern MAPS *cleanup_send_bcc_maps;
    171 extern MAPS *cleanup_rcpt_bcc_maps;
    172 
    173  /*
    174   * Character filters.
    175   */
    176 extern VSTRING *cleanup_reject_chars;
    177 extern VSTRING *cleanup_strip_chars;
    178 
    179  /*
    180   * Milters.
    181   */
    182 extern MILTERS *cleanup_milters;
    183 
    184  /*
    185   * Address canonicalization fine control.
    186   */
    187 #define CLEANUP_CANON_FLAG_ENV_FROM	(1<<0)	/* envelope sender */
    188 #define CLEANUP_CANON_FLAG_ENV_RCPT	(1<<1)	/* envelope recipient */
    189 #define CLEANUP_CANON_FLAG_HDR_FROM	(1<<2)	/* header sender */
    190 #define CLEANUP_CANON_FLAG_HDR_RCPT	(1<<3)	/* header recipient */
    191 
    192  /*
    193   * Address masquerading fine control.
    194   */
    195 #define CLEANUP_MASQ_FLAG_ENV_FROM	(1<<0)	/* envelope sender */
    196 #define CLEANUP_MASQ_FLAG_ENV_RCPT	(1<<1)	/* envelope recipient */
    197 #define CLEANUP_MASQ_FLAG_HDR_FROM	(1<<2)	/* header sender */
    198 #define CLEANUP_MASQ_FLAG_HDR_RCPT	(1<<3)	/* header recipient */
    199 
    200  /*
    201   * Restrictions on extension propagation.
    202   */
    203 extern int cleanup_ext_prop_mask;
    204 
    205  /*
    206   * Saved queue file names, so the files can be removed in case of a fatal
    207   * run-time error.
    208   */
    209 extern char *cleanup_path;
    210 extern VSTRING *cleanup_trace_path;
    211 extern VSTRING *cleanup_bounce_path;
    212 
    213  /*
    214   * cleanup_state.c
    215   */
    216 extern CLEANUP_STATE *cleanup_state_alloc(VSTREAM *);
    217 extern void cleanup_state_free(CLEANUP_STATE *);
    218 
    219  /*
    220   * cleanup_api.c
    221   */
    222 extern CLEANUP_STATE *cleanup_open(VSTREAM *);
    223 extern void cleanup_control(CLEANUP_STATE *, int);
    224 extern int cleanup_flush(CLEANUP_STATE *);
    225 extern void cleanup_free(CLEANUP_STATE *);
    226 extern void cleanup_all(void);
    227 extern void cleanup_sig(int);
    228 extern void cleanup_pre_jail(char *, char **);
    229 extern void cleanup_post_jail(char *, char **);
    230 extern const CONFIG_INT_TABLE cleanup_int_table[];
    231 extern const CONFIG_BOOL_TABLE cleanup_bool_table[];
    232 extern const CONFIG_NBOOL_TABLE cleanup_nbool_table[];
    233 extern const CONFIG_STR_TABLE cleanup_str_table[];
    234 extern const CONFIG_TIME_TABLE cleanup_time_table[];
    235 
    236 #define CLEANUP_RECORD(s, t, b, l)	((s)->action((s), (t), (b), (l)))
    237 
    238  /*
    239   * cleanup_out.c
    240   */
    241 extern void cleanup_out(CLEANUP_STATE *, int, const char *, ssize_t);
    242 extern void cleanup_out_string(CLEANUP_STATE *, int, const char *);
    243 extern void PRINTFLIKE(3, 4) cleanup_out_format(CLEANUP_STATE *, int, const char *,...);
    244 extern void cleanup_out_header(CLEANUP_STATE *, VSTRING *);
    245 
    246 #define CLEANUP_OUT_BUF(s, t, b) \
    247 	cleanup_out((s), (t), vstring_str((b)), VSTRING_LEN((b)))
    248 
    249 #define CLEANUP_OUT_OK(s) \
    250 	(!((s)->errs & (s)->err_mask) && !((s)->flags & CLEANUP_FLAG_DISCARD))
    251 
    252  /*
    253   * cleanup_envelope.c
    254   */
    255 extern void cleanup_envelope(CLEANUP_STATE *, int, const char *, ssize_t);
    256 
    257  /*
    258   * cleanup_message.c
    259   */
    260 extern void cleanup_message(CLEANUP_STATE *, int, const char *, ssize_t);
    261 
    262  /*
    263   * cleanup_extracted.c
    264   */
    265 extern void cleanup_extracted(CLEANUP_STATE *, int, const char *, ssize_t);
    266 
    267  /*
    268   * cleanup_final.c
    269   */
    270 extern void cleanup_final(CLEANUP_STATE *);
    271 
    272  /*
    273   * cleanup_rewrite.c
    274   */
    275 extern int cleanup_rewrite_external(const char *, VSTRING *, const char *);
    276 extern int cleanup_rewrite_internal(const char *, VSTRING *, const char *);
    277 extern int cleanup_rewrite_tree(const char *, TOK822 *);
    278 
    279  /*
    280   * cleanup_map11.c
    281   */
    282 extern int cleanup_map11_external(CLEANUP_STATE *, VSTRING *, MAPS *, int);
    283 extern int cleanup_map11_internal(CLEANUP_STATE *, VSTRING *, MAPS *, int);
    284 extern int cleanup_map11_tree(CLEANUP_STATE *, TOK822 *, MAPS *, int);
    285 
    286  /*
    287   * cleanup_map1n.c
    288   */
    289 ARGV   *cleanup_map1n_internal(CLEANUP_STATE *, const char *, MAPS *, int);
    290 
    291  /*
    292   * cleanup_masquerade.c
    293   */
    294 extern int cleanup_masquerade_external(CLEANUP_STATE *, VSTRING *, ARGV *);
    295 extern int cleanup_masquerade_internal(CLEANUP_STATE *, VSTRING *, ARGV *);
    296 extern int cleanup_masquerade_tree(CLEANUP_STATE *, TOK822 *, ARGV *);
    297 
    298  /*
    299   * cleanup_recipient.c
    300   */
    301 extern void cleanup_out_recipient(CLEANUP_STATE *, const char *, int, const char *, const char *);
    302 
    303  /*
    304   * cleanup_addr.c.
    305   */
    306 extern off_t cleanup_addr_sender(CLEANUP_STATE *, const char *);
    307 extern void cleanup_addr_recipient(CLEANUP_STATE *, const char *);
    308 extern void cleanup_addr_bcc_dsn(CLEANUP_STATE *, const char *, const char *, int);
    309 
    310 #define NO_DSN_ORCPT	((char *) 0)
    311 #define NO_DSN_NOTIFY	DSN_NOTIFY_NEVER
    312 #define DEF_DSN_NOTIFY	(0)
    313 
    314 #define cleanup_addr_bcc(state, addr) \
    315     cleanup_addr_bcc_dsn((state), (addr), NO_DSN_ORCPT, NO_DSN_NOTIFY)
    316 
    317  /*
    318   * cleanup_bounce.c.
    319   */
    320 extern int cleanup_bounce(CLEANUP_STATE *);
    321 
    322  /*
    323   * MSG_STATS compatibility.
    324   */
    325 #define CLEANUP_MSG_STATS(stats, state) \
    326     MSG_STATS_INIT1(stats, incoming_arrival, state->arrival_time)
    327 
    328  /*
    329   * cleanup_milter.c.
    330   */
    331 extern void cleanup_milter_header_checks_init(void);
    332 extern void cleanup_milter_receive(CLEANUP_STATE *, int);
    333 extern void cleanup_milter_inspect(CLEANUP_STATE *, MILTERS *);
    334 extern void cleanup_milter_emul_mail(CLEANUP_STATE *, MILTERS *, const char *);
    335 extern void cleanup_milter_emul_rcpt(CLEANUP_STATE *, MILTERS *, const char *);
    336 extern void cleanup_milter_emul_data(CLEANUP_STATE *, MILTERS *);
    337 
    338 #define CLEANUP_MILTER_OK(s) \
    339     (((s)->flags & CLEANUP_FLAG_MILTER) != 0 \
    340 	&& (s)->errs == 0 && ((s)->flags & CLEANUP_FLAG_DISCARD) == 0)
    341 
    342  /*
    343   * cleanup_body_edit.c
    344   */
    345 typedef struct CLEANUP_REGION {
    346     off_t   start;			/* start of region */
    347     off_t   len;			/* length or zero (open-ended) */
    348     off_t   write_offs;			/* write offset */
    349     struct CLEANUP_REGION *next;	/* linkage */
    350 } CLEANUP_REGION;
    351 
    352 extern void cleanup_region_init(CLEANUP_STATE *);
    353 extern CLEANUP_REGION *cleanup_region_open(CLEANUP_STATE *, ssize_t);
    354 extern void cleanup_region_close(CLEANUP_STATE *, CLEANUP_REGION *);
    355 extern CLEANUP_REGION *cleanup_region_return(CLEANUP_STATE *, CLEANUP_REGION *);
    356 extern void cleanup_region_done(CLEANUP_STATE *);
    357 
    358 extern int cleanup_body_edit_start(CLEANUP_STATE *);
    359 extern int cleanup_body_edit_write(CLEANUP_STATE *, int, VSTRING *);
    360 extern int cleanup_body_edit_finish(CLEANUP_STATE *);
    361 extern void cleanup_body_edit_free(CLEANUP_STATE *);
    362 
    363  /*
    364   * From: header formatting.
    365   */
    366 extern int cleanup_hfrom_format;
    367 
    368  /*
    369   * How to handle garbage at end of the primary message header.
    370   */
    371 #define NON_EMPTY_EOH_CODE_ERROR	-1	/* sentinel */
    372 #define NON_EMPTY_EOH_CODE_FIX_QUIETLY	0
    373 #define NON_EMPTY_EOH_CODE_ADD_HDR	1
    374 #define NON_EMPTY_EOH_CODE_REJECT	2
    375 
    376 extern int cleanup_non_empty_eoh_action;
    377 
    378 /* LICENSE
    379 /* .ad
    380 /* .fi
    381 /*	The Secure Mailer license must be distributed with this software.
    382 /* AUTHOR(S)
    383 /*	Wietse Venema
    384 /*	IBM T.J. Watson Research
    385 /*	P.O. Box 704
    386 /*	Yorktown Heights, NY 10598, USA
    387 /*
    388 /*	Wietse Venema
    389 /*	Google, Inc.
    390 /*	111 8th Avenue
    391 /*	New York, NY 10011, USA
    392 /*
    393 /*	Wietse Venema
    394 /*	porcupine.org
    395 /*--*/
    396