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