1 /* $NetBSD: cleanup.h,v 1.11 2025/02/25 19:15:44 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 } CLEANUP_STATE; 139 140 /* 141 * Status flags. Flags 0-15 are reserved for cleanup_user.h. 142 */ 143 #define CLEANUP_FLAG_INRCPT (1<<16) /* Processing recipient records */ 144 #define CLEANUP_FLAG_WARN_SEEN (1<<17) /* REC_TYPE_WARN record seen */ 145 #define CLEANUP_FLAG_END_SEEN (1<<18) /* REC_TYPE_END record seen */ 146 147 /* 148 * Bit mask for the CLEANUP_STATE.headers_seen member. 149 */ 150 #define HDRS_SEEN_MASK(hval) ((uint64_t) 1 << (hval)) 151 152 /* 153 * Mappings. 154 */ 155 extern MAPS *cleanup_comm_canon_maps; 156 extern MAPS *cleanup_send_canon_maps; 157 extern MAPS *cleanup_rcpt_canon_maps; 158 extern int cleanup_comm_canon_flags; 159 extern int cleanup_send_canon_flags; 160 extern int cleanup_rcpt_canon_flags; 161 extern MAPS *cleanup_header_checks; 162 extern MAPS *cleanup_mimehdr_checks; 163 extern MAPS *cleanup_nesthdr_checks; 164 extern MAPS *cleanup_body_checks; 165 extern MAPS *cleanup_virt_alias_maps; 166 extern ARGV *cleanup_masq_domains; 167 extern STRING_LIST *cleanup_masq_exceptions; 168 extern int cleanup_masq_flags; 169 extern MAPS *cleanup_send_bcc_maps; 170 extern MAPS *cleanup_rcpt_bcc_maps; 171 172 /* 173 * Character filters. 174 */ 175 extern VSTRING *cleanup_reject_chars; 176 extern VSTRING *cleanup_strip_chars; 177 178 /* 179 * Milters. 180 */ 181 extern MILTERS *cleanup_milters; 182 183 /* 184 * Address canonicalization fine control. 185 */ 186 #define CLEANUP_CANON_FLAG_ENV_FROM (1<<0) /* envelope sender */ 187 #define CLEANUP_CANON_FLAG_ENV_RCPT (1<<1) /* envelope recipient */ 188 #define CLEANUP_CANON_FLAG_HDR_FROM (1<<2) /* header sender */ 189 #define CLEANUP_CANON_FLAG_HDR_RCPT (1<<3) /* header recipient */ 190 191 /* 192 * Address masquerading fine control. 193 */ 194 #define CLEANUP_MASQ_FLAG_ENV_FROM (1<<0) /* envelope sender */ 195 #define CLEANUP_MASQ_FLAG_ENV_RCPT (1<<1) /* envelope recipient */ 196 #define CLEANUP_MASQ_FLAG_HDR_FROM (1<<2) /* header sender */ 197 #define CLEANUP_MASQ_FLAG_HDR_RCPT (1<<3) /* header recipient */ 198 199 /* 200 * Restrictions on extension propagation. 201 */ 202 extern int cleanup_ext_prop_mask; 203 204 /* 205 * Saved queue file names, so the files can be removed in case of a fatal 206 * run-time error. 207 */ 208 extern char *cleanup_path; 209 extern VSTRING *cleanup_trace_path; 210 extern VSTRING *cleanup_bounce_path; 211 212 /* 213 * cleanup_state.c 214 */ 215 extern CLEANUP_STATE *cleanup_state_alloc(VSTREAM *); 216 extern void cleanup_state_free(CLEANUP_STATE *); 217 218 /* 219 * cleanup_api.c 220 */ 221 extern CLEANUP_STATE *cleanup_open(VSTREAM *); 222 extern void cleanup_control(CLEANUP_STATE *, int); 223 extern int cleanup_flush(CLEANUP_STATE *); 224 extern void cleanup_free(CLEANUP_STATE *); 225 extern void cleanup_all(void); 226 extern void cleanup_sig(int); 227 extern void cleanup_pre_jail(char *, char **); 228 extern void cleanup_post_jail(char *, char **); 229 extern const CONFIG_INT_TABLE cleanup_int_table[]; 230 extern const CONFIG_BOOL_TABLE cleanup_bool_table[]; 231 extern const CONFIG_STR_TABLE cleanup_str_table[]; 232 extern const CONFIG_TIME_TABLE cleanup_time_table[]; 233 234 #define CLEANUP_RECORD(s, t, b, l) ((s)->action((s), (t), (b), (l))) 235 236 /* 237 * cleanup_out.c 238 */ 239 extern void cleanup_out(CLEANUP_STATE *, int, const char *, ssize_t); 240 extern void cleanup_out_string(CLEANUP_STATE *, int, const char *); 241 extern void PRINTFLIKE(3, 4) cleanup_out_format(CLEANUP_STATE *, int, const char *,...); 242 extern void cleanup_out_header(CLEANUP_STATE *, VSTRING *); 243 244 #define CLEANUP_OUT_BUF(s, t, b) \ 245 cleanup_out((s), (t), vstring_str((b)), VSTRING_LEN((b))) 246 247 #define CLEANUP_OUT_OK(s) \ 248 (!((s)->errs & (s)->err_mask) && !((s)->flags & CLEANUP_FLAG_DISCARD)) 249 250 /* 251 * cleanup_envelope.c 252 */ 253 extern void cleanup_envelope(CLEANUP_STATE *, int, const char *, ssize_t); 254 255 /* 256 * cleanup_message.c 257 */ 258 extern void cleanup_message(CLEANUP_STATE *, int, const char *, ssize_t); 259 260 /* 261 * cleanup_extracted.c 262 */ 263 extern void cleanup_extracted(CLEANUP_STATE *, int, const char *, ssize_t); 264 265 /* 266 * cleanup_final.c 267 */ 268 extern void cleanup_final(CLEANUP_STATE *); 269 270 /* 271 * cleanup_rewrite.c 272 */ 273 extern int cleanup_rewrite_external(const char *, VSTRING *, const char *); 274 extern int cleanup_rewrite_internal(const char *, VSTRING *, const char *); 275 extern int cleanup_rewrite_tree(const char *, TOK822 *); 276 277 /* 278 * cleanup_map11.c 279 */ 280 extern int cleanup_map11_external(CLEANUP_STATE *, VSTRING *, MAPS *, int); 281 extern int cleanup_map11_internal(CLEANUP_STATE *, VSTRING *, MAPS *, int); 282 extern int cleanup_map11_tree(CLEANUP_STATE *, TOK822 *, MAPS *, int); 283 284 /* 285 * cleanup_map1n.c 286 */ 287 ARGV *cleanup_map1n_internal(CLEANUP_STATE *, const char *, MAPS *, int); 288 289 /* 290 * cleanup_masquerade.c 291 */ 292 extern int cleanup_masquerade_external(CLEANUP_STATE *, VSTRING *, ARGV *); 293 extern int cleanup_masquerade_internal(CLEANUP_STATE *, VSTRING *, ARGV *); 294 extern int cleanup_masquerade_tree(CLEANUP_STATE *, TOK822 *, ARGV *); 295 296 /* 297 * cleanup_recipient.c 298 */ 299 extern void cleanup_out_recipient(CLEANUP_STATE *, const char *, int, const char *, const char *); 300 301 /* 302 * cleanup_addr.c. 303 */ 304 extern off_t cleanup_addr_sender(CLEANUP_STATE *, const char *); 305 extern void cleanup_addr_recipient(CLEANUP_STATE *, const char *); 306 extern void cleanup_addr_bcc_dsn(CLEANUP_STATE *, const char *, const char *, int); 307 308 #define NO_DSN_ORCPT ((char *) 0) 309 #define NO_DSN_NOTIFY DSN_NOTIFY_NEVER 310 #define DEF_DSN_NOTIFY (0) 311 312 #define cleanup_addr_bcc(state, addr) \ 313 cleanup_addr_bcc_dsn((state), (addr), NO_DSN_ORCPT, NO_DSN_NOTIFY) 314 315 /* 316 * cleanup_bounce.c. 317 */ 318 extern int cleanup_bounce(CLEANUP_STATE *); 319 320 /* 321 * MSG_STATS compatibility. 322 */ 323 #define CLEANUP_MSG_STATS(stats, state) \ 324 MSG_STATS_INIT1(stats, incoming_arrival, state->arrival_time) 325 326 /* 327 * cleanup_milter.c. 328 */ 329 extern void cleanup_milter_header_checks_init(void); 330 extern void cleanup_milter_receive(CLEANUP_STATE *, int); 331 extern void cleanup_milter_inspect(CLEANUP_STATE *, MILTERS *); 332 extern void cleanup_milter_emul_mail(CLEANUP_STATE *, MILTERS *, const char *); 333 extern void cleanup_milter_emul_rcpt(CLEANUP_STATE *, MILTERS *, const char *); 334 extern void cleanup_milter_emul_data(CLEANUP_STATE *, MILTERS *); 335 336 #define CLEANUP_MILTER_OK(s) \ 337 (((s)->flags & CLEANUP_FLAG_MILTER) != 0 \ 338 && (s)->errs == 0 && ((s)->flags & CLEANUP_FLAG_DISCARD) == 0) 339 340 /* 341 * cleanup_body_edit.c 342 */ 343 typedef struct CLEANUP_REGION { 344 off_t start; /* start of region */ 345 off_t len; /* length or zero (open-ended) */ 346 off_t write_offs; /* write offset */ 347 struct CLEANUP_REGION *next; /* linkage */ 348 } CLEANUP_REGION; 349 350 extern void cleanup_region_init(CLEANUP_STATE *); 351 extern CLEANUP_REGION *cleanup_region_open(CLEANUP_STATE *, ssize_t); 352 extern void cleanup_region_close(CLEANUP_STATE *, CLEANUP_REGION *); 353 extern CLEANUP_REGION *cleanup_region_return(CLEANUP_STATE *, CLEANUP_REGION *); 354 extern void cleanup_region_done(CLEANUP_STATE *); 355 356 extern int cleanup_body_edit_start(CLEANUP_STATE *); 357 extern int cleanup_body_edit_write(CLEANUP_STATE *, int, VSTRING *); 358 extern int cleanup_body_edit_finish(CLEANUP_STATE *); 359 extern void cleanup_body_edit_free(CLEANUP_STATE *); 360 361 /* 362 * From: header formatting. 363 */ 364 extern int cleanup_hfrom_format; 365 366 /* LICENSE 367 /* .ad 368 /* .fi 369 /* The Secure Mailer license must be distributed with this software. 370 /* AUTHOR(S) 371 /* Wietse Venema 372 /* IBM T.J. Watson Research 373 /* P.O. Box 704 374 /* Yorktown Heights, NY 10598, USA 375 /* 376 /* Wietse Venema 377 /* Google, Inc. 378 /* 111 8th Avenue 379 /* New York, NY 10011, USA 380 /* 381 /* Wietse Venema 382 /* porcupine.org 383 /*--*/ 384